2 * Driver interaction with Linux MACsec kernel module
3 * Copyright (c) 2016, Sabrina Dubroca <sd@queasysnail.net> and Red Hat, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
10 #include <sys/ioctl.h>
12 #include <netpacket/packet.h>
13 #include <net/if_arp.h>
15 #include <netlink/netlink.h>
16 #include <netlink/genl/genl.h>
17 #include <netlink/genl/ctrl.h>
18 #include <netlink/route/link.h>
19 #include <netlink/route/link/macsec.h>
20 #include <linux/if_macsec.h>
23 #include "utils/common.h"
24 #include "utils/eloop.h"
25 #include "pae/ieee802_1x_kay.h"
27 #include "driver_wired_common.h"
29 #define DRV_PREFIX "macsec_linux: "
31 #define UNUSED_SCI 0xffffffffffffffff
34 struct macsec_drv_data *drv;
42 struct macsec_genl_ctx {
48 struct macsec_drv_data {
49 struct driver_wired_common_data common;
50 struct rtnl_link *link;
51 struct nl_cache *link_cache;
53 struct macsec_genl_ctx ctx;
55 struct netlink_data *netlink;
57 char ifname[IFNAMSIZ + 1];
63 Boolean controlled_port_enabled;
64 Boolean controlled_port_enabled_set;
66 Boolean protect_frames;
67 Boolean protect_frames_set;
72 Boolean replay_protect;
73 Boolean replay_protect_set;
78 Boolean encoding_sa_set;
82 static int dump_callback(struct nl_msg *msg, void *argp);
85 static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd,
86 const struct macsec_genl_ctx *ctx,
93 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc message");
97 if (!genlmsg_put(msg, 0, 0, ctx->macsec_genl_id, 0, 0, cmd, 0)) {
98 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to put header");
102 NLA_PUT_U32(msg, MACSEC_ATTR_IFINDEX, ifindex);
112 static int nla_put_rxsc_config(struct nl_msg *msg, u64 sci)
114 struct nlattr *nest = nla_nest_start(msg, MACSEC_ATTR_RXSC_CONFIG);
119 NLA_PUT_U64(msg, MACSEC_RXSC_ATTR_SCI, sci);
121 nla_nest_end(msg, nest);
130 static int init_genl_ctx(struct macsec_drv_data *drv)
132 struct macsec_genl_ctx *ctx = &drv->ctx;
134 ctx->sk = nl_socket_alloc();
136 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
140 if (genl_connect(ctx->sk) < 0) {
141 wpa_printf(MSG_ERROR,
142 DRV_PREFIX "connection to genl socket failed");
146 ctx->macsec_genl_id = genl_ctrl_resolve(ctx->sk, "macsec");
147 if (ctx->macsec_genl_id < 0) {
148 wpa_printf(MSG_ERROR, DRV_PREFIX "genl resolve failed");
152 memset(&ctx->cb_arg, 0, sizeof(ctx->cb_arg));
153 ctx->cb_arg.drv = drv;
155 nl_socket_modify_cb(ctx->sk, NL_CB_VALID, NL_CB_CUSTOM, dump_callback,
161 nl_socket_free(ctx->sk);
167 static int try_commit(struct macsec_drv_data *drv)
177 if (drv->controlled_port_enabled_set) {
178 struct rtnl_link *change = rtnl_link_alloc();
183 rtnl_link_set_name(change, drv->ifname);
185 if (drv->controlled_port_enabled)
186 rtnl_link_set_flags(change, IFF_UP);
188 rtnl_link_unset_flags(change, IFF_UP);
190 err = rtnl_link_change(drv->sk, change, change, 0);
194 rtnl_link_put(change);
196 drv->controlled_port_enabled_set = FALSE;
199 if (drv->protect_frames_set)
200 rtnl_link_macsec_set_protect(drv->link, drv->protect_frames);
202 if (drv->encrypt_set)
203 rtnl_link_macsec_set_encrypt(drv->link, drv->encrypt);
205 if (drv->replay_protect_set) {
206 rtnl_link_macsec_set_replay_protect(drv->link,
207 drv->replay_protect);
208 if (drv->replay_protect)
209 rtnl_link_macsec_set_window(drv->link,
213 if (drv->encoding_sa_set)
214 rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa);
216 err = rtnl_link_add(drv->sk, drv->link, 0);
220 drv->protect_frames_set = FALSE;
221 drv->encrypt_set = FALSE;
222 drv->replay_protect_set = FALSE;
228 static void macsec_drv_wpa_deinit(void *priv)
230 struct macsec_drv_data *drv = priv;
232 driver_wired_deinit_common(&drv->common);
237 static int macsec_check_macsec(void)
242 sk = nl_socket_alloc();
244 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
248 if (genl_connect(sk) < 0) {
249 wpa_printf(MSG_ERROR,
250 DRV_PREFIX "connection to genl socket failed");
254 if (genl_ctrl_resolve(sk, "macsec") < 0) {
255 wpa_printf(MSG_ERROR,
256 DRV_PREFIX "genl resolve failed - macsec kernel module not present?");
268 static void * macsec_drv_wpa_init(void *ctx, const char *ifname)
270 struct macsec_drv_data *drv;
272 if (macsec_check_macsec() < 0)
275 drv = os_zalloc(sizeof(*drv));
279 if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
288 static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params)
290 struct macsec_drv_data *drv = priv;
293 wpa_printf(MSG_DEBUG, "%s", __func__);
295 drv->sk = nl_socket_alloc();
299 err = nl_connect(drv->sk, NETLINK_ROUTE);
301 wpa_printf(MSG_ERROR, DRV_PREFIX
302 "Unable to connect NETLINK_ROUTE socket: %s",
307 err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache);
309 wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s",
314 drv->parent_ifi = rtnl_link_name2i(drv->link_cache, drv->common.ifname);
315 if (drv->parent_ifi == 0) {
316 wpa_printf(MSG_ERROR, DRV_PREFIX
317 "couldn't find ifindex for interface %s",
322 err = init_genl_ctx(drv);
329 nl_cache_free(drv->link_cache);
330 drv->link_cache = NULL;
332 nl_socket_free(drv->sk);
338 static int macsec_drv_macsec_deinit(void *priv)
340 struct macsec_drv_data *drv = priv;
342 wpa_printf(MSG_DEBUG, "%s", __func__);
345 nl_socket_free(drv->sk);
349 nl_cache_free(drv->link_cache);
350 drv->link_cache = NULL;
353 nl_socket_free(drv->ctx.sk);
359 static int macsec_drv_get_capability(void *priv, enum macsec_cap *cap)
361 wpa_printf(MSG_DEBUG, "%s", __func__);
363 *cap = MACSEC_CAP_INTEG_AND_CONF;
370 * macsec_drv_enable_protect_frames - Set protect frames status
371 * @priv: Private driver interface data
372 * @enabled: TRUE = protect frames enabled
373 * FALSE = protect frames disabled
374 * Returns: 0 on success, -1 on failure (or if not supported)
376 static int macsec_drv_enable_protect_frames(void *priv, Boolean enabled)
378 struct macsec_drv_data *drv = priv;
380 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
382 drv->protect_frames_set = TRUE;
383 drv->protect_frames = enabled;
385 return try_commit(drv);
390 * macsec_drv_enable_encrypt - Set protect frames status
391 * @priv: Private driver interface data
392 * @enabled: TRUE = protect frames enabled
393 * FALSE = protect frames disabled
394 * Returns: 0 on success, -1 on failure (or if not supported)
396 static int macsec_drv_enable_encrypt(void *priv, Boolean enabled)
398 struct macsec_drv_data *drv = priv;
400 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
402 drv->encrypt_set = TRUE;
403 drv->encrypt = enabled;
405 return try_commit(drv);
410 * macsec_drv_set_replay_protect - Set replay protect status and window size
411 * @priv: Private driver interface data
412 * @enabled: TRUE = replay protect enabled
413 * FALSE = replay protect disabled
414 * @window: replay window size, valid only when replay protect enabled
415 * Returns: 0 on success, -1 on failure (or if not supported)
417 static int macsec_drv_set_replay_protect(void *priv, Boolean enabled,
420 struct macsec_drv_data *drv = priv;
422 wpa_printf(MSG_DEBUG, "%s -> %s, %u", __func__,
423 enabled ? "TRUE" : "FALSE", window);
425 drv->replay_protect_set = TRUE;
426 drv->replay_protect = enabled;
428 drv->replay_window = window;
430 return try_commit(drv);
435 * macsec_drv_set_current_cipher_suite - Set current cipher suite
436 * @priv: Private driver interface data
437 * @cs: EUI64 identifier
438 * Returns: 0 on success, -1 on failure (or if not supported)
440 static int macsec_drv_set_current_cipher_suite(void *priv, u64 cs)
442 wpa_printf(MSG_DEBUG, "%s -> %016" PRIx64, __func__, cs);
448 * macsec_drv_enable_controlled_port - Set controlled port status
449 * @priv: Private driver interface data
450 * @enabled: TRUE = controlled port enabled
451 * FALSE = controlled port disabled
452 * Returns: 0 on success, -1 on failure (or if not supported)
454 static int macsec_drv_enable_controlled_port(void *priv, Boolean enabled)
456 struct macsec_drv_data *drv = priv;
458 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
460 drv->controlled_port_enabled = enabled;
461 drv->controlled_port_enabled_set = TRUE;
463 return try_commit(drv);
467 static struct nla_policy sa_policy[MACSEC_SA_ATTR_MAX + 1] = {
468 [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 },
469 [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 },
470 [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 },
471 [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY },
474 static struct nla_policy sc_policy[MACSEC_RXSC_ATTR_MAX + 1] = {
475 [MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 },
476 [MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 },
477 [MACSEC_RXSC_ATTR_SA_LIST] = { .type = NLA_NESTED },
480 static struct nla_policy main_policy[MACSEC_ATTR_MAX + 1] = {
481 [MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 },
482 [MACSEC_ATTR_SECY] = { .type = NLA_NESTED },
483 [MACSEC_ATTR_TXSA_LIST] = { .type = NLA_NESTED },
484 [MACSEC_ATTR_RXSC_LIST] = { .type = NLA_NESTED },
487 static int dump_callback(struct nl_msg *msg, void *argp)
489 struct nlmsghdr *ret_hdr = nlmsg_hdr(msg);
490 struct nlattr *tb_msg[MACSEC_ATTR_MAX + 1];
491 struct cb_arg *arg = (struct cb_arg *) argp;
492 struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(ret_hdr);
495 if (ret_hdr->nlmsg_type != arg->drv->ctx.macsec_genl_id)
498 err = nla_parse(tb_msg, MACSEC_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
499 genlmsg_attrlen(gnlh, 0), main_policy);
503 if (!tb_msg[MACSEC_ATTR_IFINDEX])
506 if (nla_get_u32(tb_msg[MACSEC_ATTR_IFINDEX]) != (u32) arg->ifindex)
509 if (arg->txsa < 4 && !tb_msg[MACSEC_ATTR_TXSA_LIST]) {
511 } else if (arg->txsa < 4) {
515 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_TXSA_LIST], rem) {
516 struct nlattr *tb[MACSEC_SA_ATTR_MAX + 1];
518 err = nla_parse_nested(tb, MACSEC_SA_ATTR_MAX, nla,
522 if (!tb[MACSEC_SA_ATTR_AN])
524 if (nla_get_u8(tb[MACSEC_SA_ATTR_AN]) != arg->txsa)
526 if (!tb[MACSEC_SA_ATTR_PN])
528 *arg->pn = nla_get_u32(tb[MACSEC_SA_ATTR_PN]);
535 if (arg->rxsci == UNUSED_SCI)
538 if (tb_msg[MACSEC_ATTR_RXSC_LIST]) {
542 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_RXSC_LIST], rem) {
543 struct nlattr *tb[MACSEC_RXSC_ATTR_MAX + 1];
545 err = nla_parse_nested(tb, MACSEC_RXSC_ATTR_MAX, nla,
549 if (!tb[MACSEC_RXSC_ATTR_SCI])
551 if (nla_get_u64(tb[MACSEC_RXSC_ATTR_SCI]) != arg->rxsci)
553 if (!tb[MACSEC_RXSC_ATTR_SA_LIST])
556 nla_for_each_nested(nla, tb[MACSEC_RXSC_ATTR_SA_LIST],
558 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
560 err = nla_parse_nested(tb_sa,
561 MACSEC_SA_ATTR_MAX, nla,
565 if (!tb_sa[MACSEC_SA_ATTR_AN])
567 if (nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]) !=
570 if (!tb_sa[MACSEC_SA_ATTR_PN])
573 nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
588 static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg)
592 ret = nl_send_auto_complete(sk, msg);
594 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to send: %d (%s)",
595 __func__, ret, nl_geterror(-ret));
599 ret = nl_recvmsgs_default(sk);
601 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to recv: %d (%s)",
602 __func__, ret, nl_geterror(-ret));
609 static int do_dump(struct macsec_drv_data *drv, u8 txsa, u64 rxsci, u8 rxsa,
612 struct macsec_genl_ctx *ctx = &drv->ctx;
616 ctx->cb_arg.ifindex = drv->ifi;
617 ctx->cb_arg.rxsci = rxsci;
618 ctx->cb_arg.rxsa = rxsa;
619 ctx->cb_arg.txsa = txsa;
624 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to alloc message",
629 if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->macsec_genl_id, 0,
630 NLM_F_DUMP, MACSEC_CMD_GET_TXSC, 0)) {
631 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to put header",
636 ret = nl_send_recv(ctx->sk, msg);
638 wpa_printf(MSG_ERROR,
639 DRV_PREFIX "failed to communicate: %d (%s)",
640 ret, nl_geterror(-ret));
642 ctx->cb_arg.pn = NULL;
651 * macsec_drv_get_receive_lowest_pn - Get receive lowest PN
652 * @priv: Private driver interface data
653 * @sa: secure association
654 * Returns: 0 on success, -1 on failure (or if not supported)
656 static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
658 struct macsec_drv_data *drv = priv;
661 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s", __func__);
663 err = do_dump(drv, 0xff, mka_sci_u64(&sa->sc->sci), sa->an,
665 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: result %d", __func__,
673 * macsec_drv_get_transmit_next_pn - Get transmit next PN
674 * @priv: Private driver interface data
675 * @sa: secure association
676 * Returns: 0 on success, -1 on failure (or if not supported)
678 static int macsec_drv_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
680 struct macsec_drv_data *drv = priv;
683 wpa_printf(MSG_DEBUG, "%s", __func__);
685 err = do_dump(drv, sa->an, UNUSED_SCI, 0xff, &sa->next_pn);
686 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: err %d result %d", __func__, err,
693 * macsec_drv_set_transmit_next_pn - Set transmit next pn
694 * @priv: Private driver interface data
695 * @sa: secure association
696 * Returns: 0 on success, -1 on failure (or if not supported)
698 static int macsec_drv_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
700 struct macsec_drv_data *drv = priv;
701 struct macsec_genl_ctx *ctx = &drv->ctx;
706 wpa_printf(MSG_DEBUG, "%s -> %d: %d", __func__, sa->an, sa->next_pn);
708 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, drv->ifi);
712 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
714 goto nla_put_failure;
716 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
717 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
719 nla_nest_end(msg, nest);
721 ret = nl_send_recv(ctx->sk, msg);
723 wpa_printf(MSG_ERROR,
724 DRV_PREFIX "failed to communicate: %d (%s)",
725 ret, nl_geterror(-ret));
734 #define SCISTR MACSTR "::%hx"
735 #define SCI2STR(addr, port) MAC2STR(addr), htons(port)
738 * macsec_drv_create_receive_sc - Create secure channel for receiving
739 * @priv: Private driver interface data
740 * @sc: secure channel
741 * @sci_addr: secure channel identifier - address
742 * @sci_port: secure channel identifier - port
743 * @conf_offset: confidentiality offset (0, 30, or 50)
744 * @validation: frame validation policy (0 = Disabled, 1 = Checked,
746 * Returns: 0 on success, -1 on failure (or if not supported)
748 static int macsec_drv_create_receive_sc(void *priv, struct receive_sc *sc,
749 unsigned int conf_offset,
752 struct macsec_drv_data *drv = priv;
753 struct macsec_genl_ctx *ctx = &drv->ctx;
757 wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__,
758 SCI2STR(sc->sci.addr, sc->sci.port));
760 msg = msg_prepare(MACSEC_CMD_ADD_RXSC, ctx, drv->ifi);
764 if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
765 goto nla_put_failure;
767 ret = nl_send_recv(ctx->sk, msg);
769 wpa_printf(MSG_ERROR,
770 DRV_PREFIX "%s: failed to communicate: %d (%s)",
771 __func__, ret, nl_geterror(-ret));
781 * macsec_drv_delete_receive_sc - Delete secure connection for receiving
782 * @priv: private driver interface data from init()
783 * @sc: secure channel
784 * Returns: 0 on success, -1 on failure
786 static int macsec_drv_delete_receive_sc(void *priv, struct receive_sc *sc)
788 struct macsec_drv_data *drv = priv;
789 struct macsec_genl_ctx *ctx = &drv->ctx;
793 wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__,
794 SCI2STR(sc->sci.addr, sc->sci.port));
796 msg = msg_prepare(MACSEC_CMD_DEL_RXSC, ctx, drv->ifi);
800 if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
801 goto nla_put_failure;
803 ret = nl_send_recv(ctx->sk, msg);
805 wpa_printf(MSG_ERROR,
806 DRV_PREFIX "%s: failed to communicate: %d (%s)",
807 __func__, ret, nl_geterror(-ret));
817 * macsec_drv_create_receive_sa - Create secure association for receive
818 * @priv: private driver interface data from init()
819 * @sa: secure association
820 * Returns: 0 on success, -1 on failure
822 static int macsec_drv_create_receive_sa(void *priv, struct receive_sa *sa)
824 struct macsec_drv_data *drv = priv;
825 struct macsec_genl_ctx *ctx = &drv->ctx;
830 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
831 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
833 msg = msg_prepare(MACSEC_CMD_ADD_RXSA, ctx, drv->ifi);
837 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
838 goto nla_put_failure;
840 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
842 goto nla_put_failure;
844 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
845 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_receive);
846 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
847 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
848 &sa->pkey->key_identifier);
849 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
851 nla_nest_end(msg, nest);
853 ret = nl_send_recv(ctx->sk, msg);
855 wpa_printf(MSG_ERROR,
856 DRV_PREFIX "%s: failed to communicate: %d (%s)",
857 __func__, ret, nl_geterror(-ret));
867 * macsec_drv_delete_receive_sa - Delete secure association for receive
868 * @priv: private driver interface data from init()
869 * @sa: secure association
870 * Returns: 0 on success, -1 on failure
872 static int macsec_drv_delete_receive_sa(void *priv, struct receive_sa *sa)
874 struct macsec_drv_data *drv = priv;
875 struct macsec_genl_ctx *ctx = &drv->ctx;
880 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
881 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
883 msg = msg_prepare(MACSEC_CMD_DEL_RXSA, ctx, drv->ifi);
887 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
888 goto nla_put_failure;
890 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
892 goto nla_put_failure;
894 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
896 nla_nest_end(msg, nest);
898 ret = nl_send_recv(ctx->sk, msg);
900 wpa_printf(MSG_ERROR,
901 DRV_PREFIX "%s: failed to communicate: %d (%s)",
902 __func__, ret, nl_geterror(-ret));
911 static int set_active_rx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
912 u64 sci, unsigned char an, Boolean state)
918 msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, ifindex);
922 if (nla_put_rxsc_config(msg, sci))
923 goto nla_put_failure;
925 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
927 goto nla_put_failure;
929 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
930 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
932 nla_nest_end(msg, nest);
934 ret = nl_send_recv(ctx->sk, msg);
936 wpa_printf(MSG_ERROR,
937 DRV_PREFIX "%s: failed to communicate: %d (%s)",
938 __func__, ret, nl_geterror(-ret));
947 * macsec_drv_enable_receive_sa - Enable the SA for receive
948 * @priv: private driver interface data from init()
949 * @sa: secure association
950 * Returns: 0 on success, -1 on failure
952 static int macsec_drv_enable_receive_sa(void *priv, struct receive_sa *sa)
954 struct macsec_drv_data *drv = priv;
955 struct macsec_genl_ctx *ctx = &drv->ctx;
957 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
958 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
960 return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
966 * macsec_drv_disable_receive_sa - Disable SA for receive
967 * @priv: private driver interface data from init()
968 * @sa: secure association
969 * Returns: 0 on success, -1 on failure
971 static int macsec_drv_disable_receive_sa(void *priv, struct receive_sa *sa)
973 struct macsec_drv_data *drv = priv;
974 struct macsec_genl_ctx *ctx = &drv->ctx;
976 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
977 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
979 return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
984 static struct rtnl_link * lookup_sc(struct nl_cache *cache, int parent, u64 sci)
986 struct rtnl_link *needle;
989 needle = rtnl_link_macsec_alloc();
993 rtnl_link_set_link(needle, parent);
994 rtnl_link_macsec_set_sci(needle, sci);
996 match = nl_cache_find(cache, (struct nl_object *) needle);
997 rtnl_link_put(needle);
999 return (struct rtnl_link *) match;
1004 * macsec_drv_create_transmit_sc - Create secure connection for transmit
1005 * @priv: private driver interface data from init()
1006 * @sc: secure channel
1007 * @conf_offset: confidentiality offset
1008 * Returns: 0 on success, -1 on failure
1010 static int macsec_drv_create_transmit_sc(
1011 void *priv, struct transmit_sc *sc,
1012 unsigned int conf_offset)
1014 struct macsec_drv_data *drv = priv;
1015 struct rtnl_link *link;
1020 wpa_printf(MSG_DEBUG, "%s", __func__);
1023 wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket");
1027 link = rtnl_link_macsec_alloc();
1029 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1033 rtnl_link_set_link(link, drv->parent_ifi);
1035 sci = mka_sci_u64(&sc->sci);
1036 rtnl_link_macsec_set_sci(link, sci);
1038 drv->created_link = TRUE;
1040 err = rtnl_link_add(drv->sk, link, NLM_F_CREATE);
1041 if (err == -NLE_BUSY) {
1042 wpa_printf(MSG_INFO,
1043 DRV_PREFIX "link already exists, using it");
1044 drv->created_link = FALSE;
1045 } else if (err < 0) {
1046 rtnl_link_put(link);
1047 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't create link: err %d",
1052 rtnl_link_put(link);
1054 nl_cache_refill(drv->sk, drv->link_cache);
1055 link = lookup_sc(drv->link_cache, drv->parent_ifi, sci);
1057 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link");
1061 drv->ifi = rtnl_link_get_ifindex(link);
1062 ifname = rtnl_link_get_name(link);
1063 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1064 rtnl_link_put(link);
1066 drv->link = rtnl_link_macsec_alloc();
1068 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1072 rtnl_link_set_name(drv->link, drv->ifname);
1074 /* In case some settings have already been done but we couldn't apply
1076 return try_commit(drv);
1081 * macsec_drv_delete_transmit_sc - Delete secure connection for transmit
1082 * @priv: private driver interface data from init()
1083 * @sc: secure channel
1084 * Returns: 0 on success, -1 on failure
1086 static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc)
1088 struct macsec_drv_data *drv = priv;
1091 wpa_printf(MSG_DEBUG, "%s", __func__);
1096 if (!drv->created_link) {
1097 rtnl_link_put(drv->link);
1099 wpa_printf(MSG_DEBUG, DRV_PREFIX
1100 "we didn't create the link, leave it alone");
1104 err = rtnl_link_delete(drv->sk, drv->link);
1106 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link");
1107 rtnl_link_put(drv->link);
1115 * macsec_drv_create_transmit_sa - Create secure association for transmit
1116 * @priv: private driver interface data from init()
1117 * @sa: secure association
1118 * Returns: 0 on success, -1 on failure
1120 static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa)
1122 struct macsec_drv_data *drv = priv;
1123 struct macsec_genl_ctx *ctx = &drv->ctx;
1125 struct nlattr *nest;
1128 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1130 msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi);
1134 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1136 goto nla_put_failure;
1138 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1139 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
1140 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
1141 &sa->pkey->key_identifier);
1142 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
1143 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit);
1145 nla_nest_end(msg, nest);
1147 ret = nl_send_recv(ctx->sk, msg);
1149 wpa_printf(MSG_ERROR,
1150 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1151 __func__, ret, nl_geterror(-ret));
1161 * macsec_drv_delete_transmit_sa - Delete secure association for transmit
1162 * @priv: private driver interface data from init()
1163 * @sa: secure association
1164 * Returns: 0 on success, -1 on failure
1166 static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa)
1168 struct macsec_drv_data *drv = priv;
1169 struct macsec_genl_ctx *ctx = &drv->ctx;
1171 struct nlattr *nest;
1174 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1176 msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi);
1180 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1182 goto nla_put_failure;
1184 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1186 nla_nest_end(msg, nest);
1188 ret = nl_send_recv(ctx->sk, msg);
1190 wpa_printf(MSG_ERROR,
1191 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1192 __func__, ret, nl_geterror(-ret));
1201 static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
1202 unsigned char an, Boolean state)
1205 struct nlattr *nest;
1208 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex);
1212 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1214 goto nla_put_failure;
1216 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
1217 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
1219 nla_nest_end(msg, nest);
1221 ret = nl_send_recv(ctx->sk, msg);
1223 wpa_printf(MSG_ERROR,
1224 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1225 __func__, ret, nl_geterror(-ret));
1235 * macsec_drv_enable_transmit_sa - Enable SA for transmit
1236 * @priv: private driver interface data from init()
1237 * @sa: secure association
1238 * Returns: 0 on success, -1 on failure
1240 static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa)
1242 struct macsec_drv_data *drv = priv;
1243 struct macsec_genl_ctx *ctx = &drv->ctx;
1246 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1248 ret = set_active_tx_sa(ctx, drv->ifi, sa->an, TRUE);
1250 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa");
1254 drv->encoding_sa_set = TRUE;
1255 drv->encoding_sa = sa->an;
1257 return try_commit(drv);
1262 * macsec_drv_disable_transmit_sa - Disable SA for transmit
1263 * @priv: private driver interface data from init()
1264 * @sa: secure association
1265 * Returns: 0 on success, -1 on failure
1267 static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa)
1269 struct macsec_drv_data *drv = priv;
1270 struct macsec_genl_ctx *ctx = &drv->ctx;
1272 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1274 return set_active_tx_sa(ctx, drv->ifi, sa->an, FALSE);
1278 const struct wpa_driver_ops wpa_driver_macsec_linux_ops = {
1279 .name = "macsec_linux",
1280 .desc = "MACsec Ethernet driver for Linux",
1281 .get_ssid = driver_wired_get_ssid,
1282 .get_bssid = driver_wired_get_bssid,
1283 .get_capa = driver_wired_get_capa,
1284 .init = macsec_drv_wpa_init,
1285 .deinit = macsec_drv_wpa_deinit,
1287 .macsec_init = macsec_drv_macsec_init,
1288 .macsec_deinit = macsec_drv_macsec_deinit,
1289 .macsec_get_capability = macsec_drv_get_capability,
1290 .enable_protect_frames = macsec_drv_enable_protect_frames,
1291 .enable_encrypt = macsec_drv_enable_encrypt,
1292 .set_replay_protect = macsec_drv_set_replay_protect,
1293 .set_current_cipher_suite = macsec_drv_set_current_cipher_suite,
1294 .enable_controlled_port = macsec_drv_enable_controlled_port,
1295 .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn,
1296 .get_transmit_next_pn = macsec_drv_get_transmit_next_pn,
1297 .set_transmit_next_pn = macsec_drv_set_transmit_next_pn,
1298 .create_receive_sc = macsec_drv_create_receive_sc,
1299 .delete_receive_sc = macsec_drv_delete_receive_sc,
1300 .create_receive_sa = macsec_drv_create_receive_sa,
1301 .delete_receive_sa = macsec_drv_delete_receive_sa,
1302 .enable_receive_sa = macsec_drv_enable_receive_sa,
1303 .disable_receive_sa = macsec_drv_disable_receive_sa,
1304 .create_transmit_sc = macsec_drv_create_transmit_sc,
1305 .delete_transmit_sc = macsec_drv_delete_transmit_sc,
1306 .create_transmit_sa = macsec_drv_create_transmit_sa,
1307 .delete_transmit_sa = macsec_drv_delete_transmit_sa,
1308 .enable_transmit_sa = macsec_drv_enable_transmit_sa,
1309 .disable_transmit_sa = macsec_drv_disable_transmit_sa,