Skip to content

Commit

Permalink
network: Introduce MACsec
Browse files Browse the repository at this point in the history
Media Access Control Security (MACsec) is an 802.1AE IEEE
industry-standard security technology that provides secure
communication for all traffic on Ethernet links.
MACsec provides point-to-point security on Ethernet links between
directly connected nodes and is capable of identifying and preventing
most security threats, including denial of service, intrusion,
man-in-the-middle, masquerading, passive wiretapping, and playback attacks.

Closes systemd#5754
  • Loading branch information
Susant Sahani authored and Eric DeVolder committed Jun 26, 2019
1 parent a1fc659 commit b92bd25
Show file tree
Hide file tree
Showing 17 changed files with 1,248 additions and 1 deletion.
121 changes: 121 additions & 0 deletions man/systemd.netdev.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@
<row><entry><varname>l2tp</varname></entry>
<entry>A Layer 2 Tunneling Protocol (L2TP) is a tunneling protocol used to support virtual private networks (VPNs) or as part of the delivery of services by ISPs. It does not provide any encryption or confidentiality by itself</entry></row>

<row><entry><varname>macsec</varname></entry>
<entry>Media Access Control Security (MACsec) is an 802.1AE IEEE industry-standard security technology that provides secure communication for all traffic on Ethernet links. MACsec provides point-to-point security on Ethernet links between directly connected nodes and is capable of identifying and preventing most security threats.</entry></row>

<row><entry><varname>vrf</varname></entry>
<entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row>

Expand Down Expand Up @@ -851,6 +854,124 @@
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[MACsec] Section Options</title>
<para>The <literal>[MACsec]</literal> section only applies for network devices of kind
<literal>macsec</literal>, and accepts the following keys:</para>

<variablelist class='network-directives'>
<varlistentry>
<term><varname>Port=</varname></term>
<listitem>
<para>Specifies the port to be used for the MACsec transmit channel. The port is used to make
secure channel identifier (SCI). Takes a value between 1 and 65535. Defaults to unset.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Encrypt=</varname></term>
<listitem>
<para>Takes a boolean. When true, enable encryption. Defaults to unset.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[MACsecReceiveChannel] Section Options</title>
<para>The <literal>[MACsecReceiveChannel]</literal> section only applies for network devices of
kind <literal>macsec</literal>, and accepts the following keys:</para>

<variablelist class='network-directives'>
<varlistentry>
<term><varname>Port=</varname></term>
<listitem>
<para>Specifies the port to be used for the MACsec receive channel. The port is used to make
secure channel identifier (SCI). Takes a value between 1 and 65535. This option is
compulsory, and is not set by default.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MACAddress=</varname></term>
<listitem>
<para>Specifies the MAC address to be used for the MACsec receive channel. The MAC address
used to make secure channel identifier (SCI). This option is compulsory, and is not set by
default.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[MACsecTransmitAssociation] Section Options</title>
<para>The <literal>[MACsecTransmitAssociation]</literal> section only applies for network devices
of kind <literal>macsec</literal>, and accepts the following keys:</para>

<variablelist class='network-directives'>
<varlistentry>
<term><varname>PacketNumber=</varname></term>
<listitem>
<para>Specifies the packet number to be used for replay protection and the construction of
the initialization vector (along with the secure channel identifier [SCI]). Takes a value
between 1-4,294,967,295. Defaults to unset.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KeyId=</varname></term>
<listitem>
<para>Specifies the identification for the key. Takes a number between 0-255. This option
is compulsory, and is not set by default.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Key=</varname></term>
<listitem>
<para>Specifies the encryption key used in the transmission channel. The same key must be
configured on the peer’s matching receive channel. This option is compulsory, and is not set
by default. Takes a 128-bit key encoded in a hexadecimal string, for example
<literal>dffafc8d7b9a43d5b9a3dfbbf6a30c16</literal>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[MACsecReceiveAssociation] Section Options</title>
<para>The <literal>[MACsecReceiveAssociation]</literal> section only applies for
network devices of kind <literal>macsec</literal>, and accepts the
following keys:</para>

<variablelist class='network-directives'>
<varlistentry>
<term><varname>Port=</varname></term>
<listitem>
<para>Accepts the same key in <literal>[MACsecReceiveChannel]</literal> section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MACAddress=</varname></term>
<listitem>
<para>Accepts the same key in <literal>[MACsecReceiveChannel]</literal> section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PacketNumber=</varname></term>
<listitem>
<para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KeyId=</varname></term>
<listitem>
<para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Key=</varname></term>
<listitem>
<para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[Tunnel] Section Options</title>

Expand Down
8 changes: 8 additions & 0 deletions man/systemd.network.xml
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,14 @@
This option may be specified more than once.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MACsec=</varname></term>
<listitem>
<para>The name of a MACsec device to create on the link. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
This option may be specified more than once.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ActiveSlave=</varname></term>
<listitem>
Expand Down
1 change: 1 addition & 0 deletions src/libsystemd/sd-netlink/generic-netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static const genl_family genl_families[] = {
[SD_GENL_WIREGUARD] = { .name = "wireguard", .version = 1 },
[SD_GENL_FOU] = { .name = "fou", .version = 1 },
[SD_GENL_L2TP] = { .name = "l2tp", .version = 1},
[SD_GENL_MACSEC] = { .name = "macsec", .version = 1},
};

int sd_genl_socket_open(sd_netlink **ret) {
Expand Down
17 changes: 17 additions & 0 deletions src/libsystemd/sd-netlink/netlink-message.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,23 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui
return 0;
}

int sd_netlink_message_append_u64(sd_netlink_message *m, unsigned short type, uint64_t data) {
int r;

assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);

r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U64);
if (r < 0)
return r;

r = add_rtattr(m, type, &data, sizeof(uint64_t));
if (r < 0)
return r;

return 0;
}

int sd_netlink_message_append_data(sd_netlink_message *m, unsigned short type, const void *data, size_t len) {
int r;

Expand Down
85 changes: 85 additions & 0 deletions src/libsystemd/sd-netlink/netlink-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/if_addrlabel.h>
#include <linux/if_bridge.h>
#include <linux/if_link.h>
#include <linux/if_macsec.h>
#include <linux/if_tunnel.h>
#include <linux/l2tp.h>
#include <linux/veth.h>
Expand Down Expand Up @@ -306,6 +307,22 @@ static const NLType rtnl_link_info_data_can_types[] = {
[IFLA_CAN_CTRLMODE] = { .size = sizeof(struct can_ctrlmode) },
};

static const NLType rtnl_link_info_data_macsec_types[] = {
[IFLA_MACSEC_SCI] = { .type = NETLINK_TYPE_U64 },
[IFLA_MACSEC_PORT] = { .type = NETLINK_TYPE_U16 },
[IFLA_MACSEC_ICV_LEN] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_CIPHER_SUITE] = { .type = NETLINK_TYPE_U64 },
[IFLA_MACSEC_WINDOW] = { .type = NETLINK_TYPE_U32 },
[IFLA_MACSEC_ENCODING_SA] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_ENCRYPT] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_PROTECT] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_INC_SCI] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_ES] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_SCB] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_REPLAY_PROTECT] = { .type = NETLINK_TYPE_U8 },
[IFLA_MACSEC_VALIDATION] = { .type = NETLINK_TYPE_U8 },
};

/* these strings must match the .kind entries in the kernel */
static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_BOND] = "bond",
Expand Down Expand Up @@ -334,6 +351,7 @@ static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard",
[NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim",
[NL_UNION_LINK_INFO_DATA_CAN] = "can",
[NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec",
};

DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
Expand Down Expand Up @@ -383,6 +401,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
.types = rtnl_link_info_data_vxcan_types },
[NL_UNION_LINK_INFO_DATA_CAN] = { .count = ELEMENTSOF(rtnl_link_info_data_can_types),
.types = rtnl_link_info_data_can_types },
[NL_UNION_LINK_INFO_DATA_MACSEC] = { .count = ELEMENTSOF(rtnl_link_info_data_macsec_types),
.types = rtnl_link_info_data_macsec_types },
};

static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
Expand Down Expand Up @@ -843,11 +863,76 @@ static const NLTypeSystem genl_l2tp_tunnel_session_type_system = {
.types = genl_l2tp,
};

static const NLType genl_rxsc_types[] = {
[MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 },
};

static const NLTypeSystem genl_rxsc_config_type_system = {
.count = ELEMENTSOF(genl_rxsc_types),
.types = genl_rxsc_types,
};

static const NLType genl_macsec_rxsc_types[] = {
[MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 },
[MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system },
};

static const NLTypeSystem genl_macsec_rxsc_type_system = {
.count = ELEMENTSOF(genl_macsec_rxsc_types),
.types = genl_macsec_rxsc_types,
};

static const NLType genl_macsec_sa_config_types[] = {
[MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 },
[MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 },
[MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 },
[MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN },
[MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN },
};

static const NLTypeSystem genl_macsec_sa_config_type_system = {
.count = ELEMENTSOF(genl_macsec_sa_config_types),
.types = genl_macsec_sa_config_types,
};

static const NLType genl_macsec_rxsa_types[] = {
[MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 },
[MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system },
};

static const NLTypeSystem genl_macsec_rxsa_type_system = {
.count = ELEMENTSOF(genl_macsec_rxsa_types),
.types = genl_macsec_rxsa_types,
};

static const NLType genl_macsec_sa_types[] = {
[MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 },
[MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system },
[MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system },
};

static const NLTypeSystem genl_macsec_sa_type_system = {
.count = ELEMENTSOF(genl_macsec_sa_types),
.types = genl_macsec_sa_types,
};

static const NLType genl_macsec[] = {
[MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system },
[MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system},
[MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system },
};

static const NLTypeSystem genl_macsec_device_type_system = {
.count = ELEMENTSOF(genl_macsec),
.types = genl_macsec,
};

static const NLType genl_families[] = {
[SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system },
[SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system },
[SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system},
[SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system },
[SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system },
};

const NLTypeSystem genl_family_type_system_root = {
Expand Down
1 change: 1 addition & 0 deletions src/libsystemd/sd-netlink/netlink-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ typedef enum NLUnionLinkInfoData {
NL_UNION_LINK_INFO_DATA_WIREGUARD,
NL_UNION_LINK_INFO_DATA_NETDEVSIM,
NL_UNION_LINK_INFO_DATA_CAN,
NL_UNION_LINK_INFO_DATA_MACSEC,
_NL_UNION_LINK_INFO_DATA_MAX,
_NL_UNION_LINK_INFO_DATA_INVALID = -1
} NLUnionLinkInfoData;
Expand Down
2 changes: 2 additions & 0 deletions src/network/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ sources = files('''
netdev/fou-tunnel.h
netdev/l2tp-tunnel.c
netdev/l2tp-tunnel.h
netdev/macsec.c
netdev/macsec.h
networkd-address-label.c
networkd-address-label.h
networkd-address-pool.c
Expand Down

0 comments on commit b92bd25

Please sign in to comment.