From da6abdba09d800c87a3a0a4c8d2bb4879a037e92 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 3 Mar 2020 11:36:16 +0100 Subject: [PATCH 1/4] macsec: report the offloading mode currently selected This patch adds support to report the MACsec offloading mode currently being enabled, which as of now can either be 'off' or 'phy'. This information is reported through the `ip macsec show` command: # ip macsec show 18: macsec0: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 3e5035b67c860001 on SA 0 0: PN 1, state on, key 00000000000000000000000000000000 RXSC: b4969112700f0001, state on 0: PN 1, state on, key 01000000000000000000000000000000 offload: phy 19: macsec1: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 3e5035b67c880001 on SA 0 1: PN 1, state on, key 00000000000000000000000000000000 RXSC: b4969112700f0001, state on 1: PN 1, state on, key 01000000000000000000000000000000 offload: off Signed-off-by: Antoine Tenart Signed-off-by: David Ahern --- ip/ipmacsec.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index ad6ad7d6..4327c796 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -31,6 +31,11 @@ static const char * const validate_str[] = { [MACSEC_VALIDATE_STRICT] = "strict", }; +static const char * const offload_str[] = { + [MACSEC_OFFLOAD_OFF] = "off", + [MACSEC_OFFLOAD_PHY] = "phy", +}; + struct sci { __u64 sci; __u16 port; @@ -605,6 +610,14 @@ static const char *cs_id_to_name(__u64 cid) } } +static const char *offload_to_str(__u8 offload) +{ + if (offload >= ARRAY_SIZE(offload_str)) + return "(unknown)"; + + return offload_str[offload]; +} + static void print_attrs(struct rtattr *attrs[]) { print_flag(attrs, "protect", MACSEC_SECY_ATTR_PROTECT); @@ -997,6 +1010,19 @@ static int process(struct nlmsghdr *n, void *arg) if (attrs[MACSEC_ATTR_RXSC_LIST]) print_rxsc_list(attrs[MACSEC_ATTR_RXSC_LIST]); + if (attrs[MACSEC_ATTR_OFFLOAD]) { + struct rtattr *attrs_offload[MACSEC_OFFLOAD_ATTR_MAX + 1]; + __u8 offload; + + parse_rtattr_nested(attrs_offload, MACSEC_OFFLOAD_ATTR_MAX, + attrs[MACSEC_ATTR_OFFLOAD]); + + offload = rta_getattr_u8(attrs_offload[MACSEC_OFFLOAD_ATTR_TYPE]); + print_string(PRINT_ANY, "offload", + " offload: %s ", offload_to_str(offload)); + print_nl(); + } + close_json_object(); return 0; From 791bc7ee482b0e48d1020888521134161f216ff5 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 3 Mar 2020 11:36:17 +0100 Subject: [PATCH 2/4] macsec: add support for changing the offloading mode MacSEC can now be offloaded to specialized hardware devices. Offloading is off by default when creating a new MACsec interface, but the mode can be updated at runtime. This patch adds a new subcommand, `ip macsec offload`, to allow users to select the offloading mode of a MACsec interface. It takes the mode to switch to as an argument, which can for now either be 'off' or 'phy': # ip macsec offload macsec0 phy # ip macsec offload macsec0 off Signed-off-by: Antoine Tenart Signed-off-by: David Ahern --- ip/ipmacsec.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index 4327c796..6104a3a5 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -98,6 +98,7 @@ static void ipmacsec_usage(void) " ip macsec del DEV rx SCI sa { 0..3 }\n" " ip macsec show\n" " ip macsec show DEV\n" + " ip macsec offload DEV [ off | phy ]\n" "where OPTS := [ pn ] [ on | off ]\n" " ID := 128-bit hex string\n" " KEY := 128-bit or 256-bit hex string\n" @@ -359,6 +360,7 @@ enum cmd { CMD_ADD, CMD_DEL, CMD_UPD, + CMD_OFFLOAD, __CMD_MAX }; @@ -375,6 +377,9 @@ static const enum macsec_nl_commands macsec_commands[__CMD_MAX][2][2] = { [0] = {-1, MACSEC_CMD_DEL_RXSC}, [1] = {MACSEC_CMD_DEL_TXSA, MACSEC_CMD_DEL_RXSA}, }, + [CMD_OFFLOAD] = { + [0] = {-1, MACSEC_CMD_UPD_OFFLOAD }, + }, }; static int do_modify_nl(enum cmd c, enum macsec_nl_commands cmd, int ifindex, @@ -534,6 +539,44 @@ static int do_modify(enum cmd c, int argc, char **argv) return -1; } +static int do_offload(enum cmd c, int argc, char **argv) +{ + enum macsec_offload offload; + struct rtattr *attr; + int ifindex, ret; + + if (argc == 0) + ipmacsec_usage(); + + ifindex = ll_name_to_index(*argv); + if (!ifindex) { + fprintf(stderr, "Device \"%s\" does not exist.\n", *argv); + return -1; + } + argc--; argv++; + + if (argc == 0) + ipmacsec_usage(); + + ret = one_of("offload", *argv, offload_str, ARRAY_SIZE(offload_str), + (int *)&offload); + if (ret) + ipmacsec_usage(); + + MACSEC_GENL_REQ(req, MACSEC_BUFLEN, macsec_commands[c][0][1], NLM_F_REQUEST); + + addattr32(&req.n, MACSEC_BUFLEN, MACSEC_ATTR_IFINDEX, ifindex); + + attr = addattr_nest(&req.n, MACSEC_BUFLEN, MACSEC_ATTR_OFFLOAD); + addattr8(&req.n, MACSEC_BUFLEN, MACSEC_OFFLOAD_ATTR_TYPE, offload); + addattr_nest_end(&req.n, attr); + + if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) + return -2; + + return 0; +} + /* dump/show */ static struct { int ifindex; @@ -1094,6 +1137,8 @@ int do_ipmacsec(int argc, char **argv) return do_modify(CMD_UPD, argc-1, argv+1); if (matches(*argv, "delete") == 0) return do_modify(CMD_DEL, argc-1, argv+1); + if (matches(*argv, "offload") == 0) + return do_offload(CMD_OFFLOAD, argc-1, argv+1); fprintf(stderr, "Command \"%s\" is unknown, try \"ip macsec help\".\n", *argv); From 69166f909b16fff8cd0af28f705b48606380c6e4 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 3 Mar 2020 11:36:18 +0100 Subject: [PATCH 3/4] man: document the ip macsec offload command Add a description of the `ip macsec offload` command used to select the offloading mode on a macsec interface when the underlying device supports it. Signed-off-by: Antoine Tenart Signed-off-by: David Ahern --- man/man8/ip-macsec.8 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/man8/ip-macsec.8 b/man/man8/ip-macsec.8 index 2179b336..d5f9d240 100644 --- a/man/man8/ip-macsec.8 +++ b/man/man8/ip-macsec.8 @@ -53,6 +53,9 @@ ip-macsec \- MACsec device configuration .BI "ip macsec del " DEV " rx " SCI " sa" .RI "{ " 0..3 " }" +.BI "ip macsec offload " DEV +.RB "{ " off " | " phy " }" + .B ip macsec show .RI [ " DEV " ] @@ -102,6 +105,10 @@ type. .SS Display MACsec configuration .nf # ip macsec show +.PP +.SS Configure offloading on an interface +.nf +# ip macsec offload macsec0 phy .SH NOTES This tool can be used to configure the 802.1AE keys of the interface. Note that 802.1AE uses GCM-AES From c15674d80d49dac94d659de443675f19e23a734e Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 3 Mar 2020 11:36:19 +0100 Subject: [PATCH 4/4] macsec: add an accessor for validate_str This patch adds an accessor for the validate_str array, to handle future changes adding a member. Signed-off-by: Antoine Tenart Signed-off-by: David Ahern --- ip/ipmacsec.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index 6104a3a5..4e500e4e 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -653,6 +653,14 @@ static const char *cs_id_to_name(__u64 cid) } } +static const char *validate_to_str(__u8 validate) +{ + if (validate >= ARRAY_SIZE(validate_str)) + return "(unknown)"; + + return validate_str[validate]; +} + static const char *offload_to_str(__u8 offload) { if (offload >= ARRAY_SIZE(offload_str)) @@ -669,7 +677,7 @@ static void print_attrs(struct rtattr *attrs[]) __u8 val = rta_getattr_u8(attrs[MACSEC_SECY_ATTR_VALIDATE]); print_string(PRINT_ANY, "validate", - "validate %s ", validate_str[val]); + "validate %s ", validate_to_str(val)); } print_flag(attrs, "sc", MACSEC_RXSC_ATTR_ACTIVE); @@ -1208,7 +1216,7 @@ static void macsec_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) print_string(PRINT_ANY, "validation", "validate %s ", - validate_str[val]); + validate_to_str(val)); } const char *inc_sci, *es, *replay;