From b0e13c3122d6836dec2ee32b2d44f0b4c163943a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 5 Apr 2019 15:52:26 +0900 Subject: [PATCH] network: add MACsecTransmitAssociation.UseForEncoding= setting --- man/systemd.netdev.xml | 8 ++ src/network/netdev/macsec.c | 73 ++++++++++++++++++- src/network/netdev/macsec.h | 3 + src/network/netdev/netdev-gperf.gperf | 1 + .../fuzz/fuzz-netdev-parser/directives.netdev | 1 + 5 files changed, 85 insertions(+), 1 deletion(-) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 030de474383..a58de37b3c9 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -948,6 +948,14 @@ unset. + + UseForEncoding= + + Takes a boolean. If enabled, then the security association is used for encoding. Only + one [MACsecTransmitAssociation] section can enable this option. When enabled, + Activate=yes is implied. Defaults to unset. + + diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c index ee1f15909e1..8e25bf6498f 100644 --- a/src/network/netdev/macsec.c +++ b/src/network/netdev/macsec.c @@ -36,6 +36,7 @@ static void security_association_init(SecurityAssociation *sa) { assert(sa); sa->activate = -1; + sa->use_for_encoding = -1; } static void macsec_receive_association_free(ReceiveAssociation *c) { @@ -539,6 +540,10 @@ static int netdev_macsec_fill_message_create(NetDev *netdev, Link *link, sd_netl return log_netdev_error_errno(netdev, r, "Could not append IFLA_MACSEC_ENCRYPT attribute: %m"); } + r = sd_netlink_message_append_u8(m, IFLA_MACSEC_ENCODING_SA, v->encoding_an); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_MACSEC_ENCODING_SA attribute: %m"); + return r; } @@ -919,6 +924,53 @@ int config_parse_macsec_sa_activate( return 0; } +int config_parse_macsec_use_for_encoding( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(macsec_transmit_association_free_or_set_invalidp) TransmitAssociation *a = NULL; + MACsec *s = userdata; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = macsec_transmit_association_new_static(s, filename, section_line, &a); + if (r < 0) + return r; + + if (isempty(rvalue)) + r = -1; + else { + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse %s= setting. Ignoring assignment: %s", + lvalue, rvalue); + return 0; + } + } + + a->sa.use_for_encoding = r; + if (a->sa.use_for_encoding > 0) + a->sa.activate = true; + + TAKE_PTR(a); + + return 0; +} + static int macsec_read_key_file(NetDev *netdev, SecurityAssociation *sa) { _cleanup_free_ uint8_t *key = NULL; size_t key_len; @@ -1095,7 +1147,8 @@ static int netdev_macsec_verify(NetDev *netdev, const char *filename) { ReceiveAssociation *n; ReceiveChannel *c; Iterator i; - uint8_t an; + uint8_t an, encoding_an; + bool use_for_encoding; int r; assert(netdev); @@ -1109,6 +1162,8 @@ static int netdev_macsec_verify(NetDev *netdev, const char *filename) { } an = 0; + use_for_encoding = false; + encoding_an = 0; ORDERED_HASHMAP_FOREACH(a, v->transmit_associations_by_section, i) { r = macsec_transmit_association_verify(a); if (r < 0) { @@ -1126,8 +1181,24 @@ static int netdev_macsec_verify(NetDev *netdev, const char *filename) { } a->sa.association_number = an++; + + if (a->sa.use_for_encoding > 0) { + if (use_for_encoding) { + log_netdev_warning(netdev, + "%s: Multiple security associations are set to be used for transmit channel." + "Disabling UseForEncoding= in [MACsecTransmitAssociation] section from line %u", + a->section->filename, a->section->line); + a->sa.use_for_encoding = false; + } else { + encoding_an = a->sa.association_number; + use_for_encoding = true; + } + } } + assert(encoding_an < MACSEC_MAX_ASSOCIATION_NUMBER); + v->encoding_an = encoding_an; + ORDERED_HASHMAP_FOREACH(n, v->receive_associations_by_section, i) { r = macsec_receive_association_verify(n); if (r < 0) diff --git a/src/network/netdev/macsec.h b/src/network/netdev/macsec.h index 167e9ca8eb3..2bd08ac5009 100644 --- a/src/network/netdev/macsec.h +++ b/src/network/netdev/macsec.h @@ -32,6 +32,7 @@ typedef struct SecurityAssociation { uint32_t key_len; char *key_file; int activate; + int use_for_encoding; } SecurityAssociation; typedef struct TransmitAssociation { @@ -63,6 +64,7 @@ struct MACsec { uint16_t port; int encrypt; + uint8_t encoding_an; OrderedHashmap *receive_channels; OrderedHashmap *receive_channels_by_section; @@ -80,3 +82,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_macsec_key_id); CONFIG_PARSER_PROTOTYPE(config_parse_macsec_key); CONFIG_PARSER_PROTOTYPE(config_parse_macsec_key_file); CONFIG_PARSER_PROTOTYPE(config_parse_macsec_sa_activate); +CONFIG_PARSER_PROTOTYPE(config_parse_macsec_use_for_encoding); diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index 20d7c143a03..a06694ad62d 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -142,6 +142,7 @@ MACsecTransmitAssociation.KeyId, config_parse_macsec_key_id, 0, MACsecTransmitAssociation.Key, config_parse_macsec_key, 0, 0 MACsecTransmitAssociation.KeyFile, config_parse_macsec_key_file, 0, 0 MACsecTransmitAssociation.Activate, config_parse_macsec_sa_activate, 0, 0 +MACsecTransmitAssociation.UseForEncoding, config_parse_macsec_use_for_encoding, 0, 0 MACsecReceiveAssociation.Port, config_parse_macsec_port, 0, 0 MACsecReceiveAssociation.MACAddress, config_parse_macsec_hw_address, 0, 0 MACsecReceiveAssociation.PacketNumber, config_parse_macsec_packet_number, 0, 0 diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev index f09b92d28ee..128f8b63415 100644 --- a/test/fuzz/fuzz-netdev-parser/directives.netdev +++ b/test/fuzz/fuzz-netdev-parser/directives.netdev @@ -185,6 +185,7 @@ KeyId= Key= KeyFile= Activate= +UseForEncoding= [MACsecReceiveChannel] Port= MACAddress=