Home | History | Annotate | Download | only in drivers
      1 /*
      2  * Driver interaction with Linux MACsec kernel module
      3  * Copyright (c) 2016, Sabrina Dubroca <sd (at) queasysnail.net> and Red Hat, Inc.
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 #include <sys/ioctl.h>
     11 #include <net/if.h>
     12 #include <netpacket/packet.h>
     13 #include <net/if_arp.h>
     14 #include <net/if.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>
     21 #include <inttypes.h>
     22 
     23 #include "utils/common.h"
     24 #include "utils/eloop.h"
     25 #include "pae/ieee802_1x_kay.h"
     26 #include "driver.h"
     27 #include "driver_wired_common.h"
     28 
     29 #define DRV_PREFIX "macsec_linux: "
     30 
     31 #define UNUSED_SCI 0xffffffffffffffff
     32 
     33 struct cb_arg {
     34 	struct macsec_drv_data *drv;
     35 	u32 *pn;
     36 	int ifindex;
     37 	u8 txsa;
     38 	u8 rxsa;
     39 	u64 rxsci;
     40 };
     41 
     42 struct macsec_genl_ctx {
     43 	struct nl_sock *sk;
     44 	int macsec_genl_id;
     45 	struct cb_arg cb_arg;
     46 };
     47 
     48 struct macsec_drv_data {
     49 	struct driver_wired_common_data common;
     50 	struct rtnl_link *link;
     51 	struct nl_cache *link_cache;
     52 	struct nl_sock *sk;
     53 	struct macsec_genl_ctx ctx;
     54 
     55 	struct netlink_data *netlink;
     56 	struct nl_handle *nl;
     57 	char ifname[IFNAMSIZ + 1];
     58 	int ifi;
     59 	int parent_ifi;
     60 
     61 	Boolean created_link;
     62 
     63 	Boolean controlled_port_enabled;
     64 	Boolean controlled_port_enabled_set;
     65 
     66 	Boolean protect_frames;
     67 	Boolean protect_frames_set;
     68 
     69 	Boolean encrypt;
     70 	Boolean encrypt_set;
     71 
     72 	Boolean replay_protect;
     73 	Boolean replay_protect_set;
     74 
     75 	u32 replay_window;
     76 
     77 	u8 encoding_sa;
     78 	Boolean encoding_sa_set;
     79 };
     80 
     81 
     82 static int dump_callback(struct nl_msg *msg, void *argp);
     83 
     84 
     85 static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd,
     86 				   const struct macsec_genl_ctx *ctx,
     87 				   unsigned int ifindex)
     88 {
     89 	struct nl_msg *msg;
     90 
     91 	msg = nlmsg_alloc();
     92 	if (!msg) {
     93 		wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc message");
     94 		return NULL;
     95 	}
     96 
     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");
     99 		goto nla_put_failure;
    100 	}
    101 
    102 	NLA_PUT_U32(msg, MACSEC_ATTR_IFINDEX, ifindex);
    103 
    104 	return msg;
    105 
    106 nla_put_failure:
    107 	nlmsg_free(msg);
    108 	return NULL;
    109 }
    110 
    111 
    112 static int nla_put_rxsc_config(struct nl_msg *msg, u64 sci)
    113 {
    114 	struct nlattr *nest = nla_nest_start(msg, MACSEC_ATTR_RXSC_CONFIG);
    115 
    116 	if (!nest)
    117 		return -1;
    118 
    119 	NLA_PUT_U64(msg, MACSEC_RXSC_ATTR_SCI, sci);
    120 
    121 	nla_nest_end(msg, nest);
    122 
    123 	return 0;
    124 
    125 nla_put_failure:
    126 	return -1;
    127 }
    128 
    129 
    130 static int init_genl_ctx(struct macsec_drv_data *drv)
    131 {
    132 	struct macsec_genl_ctx *ctx = &drv->ctx;
    133 
    134 	ctx->sk = nl_socket_alloc();
    135 	if (!ctx->sk) {
    136 		wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
    137 		return -1;
    138 	}
    139 
    140 	if (genl_connect(ctx->sk) < 0) {
    141 		wpa_printf(MSG_ERROR,
    142 			   DRV_PREFIX "connection to genl socket failed");
    143 		goto out_free;
    144 	}
    145 
    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");
    149 		goto out_free;
    150 	}
    151 
    152 	memset(&ctx->cb_arg, 0, sizeof(ctx->cb_arg));
    153 	ctx->cb_arg.drv = drv;
    154 
    155 	nl_socket_modify_cb(ctx->sk, NL_CB_VALID, NL_CB_CUSTOM, dump_callback,
    156 			    &ctx->cb_arg);
    157 
    158 	return 0;
    159 
    160 out_free:
    161 	nl_socket_free(ctx->sk);
    162 	ctx->sk = NULL;
    163 	return -1;
    164 }
    165 
    166 
    167 static int try_commit(struct macsec_drv_data *drv)
    168 {
    169 	int err;
    170 
    171 	if (!drv->sk)
    172 		return 0;
    173 
    174 	if (!drv->link)
    175 		return 0;
    176 
    177 	if (drv->controlled_port_enabled_set) {
    178 		struct rtnl_link *change = rtnl_link_alloc();
    179 
    180 		wpa_printf(MSG_DEBUG, DRV_PREFIX
    181 			   "%s: try_commit controlled_port_enabled=%d",
    182 			   drv->ifname, drv->controlled_port_enabled);
    183 		if (!change)
    184 			return -1;
    185 
    186 		rtnl_link_set_name(change, drv->ifname);
    187 
    188 		if (drv->controlled_port_enabled)
    189 			rtnl_link_set_flags(change, IFF_UP);
    190 		else
    191 			rtnl_link_unset_flags(change, IFF_UP);
    192 
    193 		err = rtnl_link_change(drv->sk, change, change, 0);
    194 		if (err < 0)
    195 			return err;
    196 
    197 		rtnl_link_put(change);
    198 
    199 		drv->controlled_port_enabled_set = FALSE;
    200 	}
    201 
    202 	if (drv->protect_frames_set) {
    203 		wpa_printf(MSG_DEBUG, DRV_PREFIX
    204 			   "%s: try_commit protect_frames=%d",
    205 			   drv->ifname, drv->protect_frames);
    206 		rtnl_link_macsec_set_protect(drv->link, drv->protect_frames);
    207 	}
    208 
    209 	if (drv->encrypt_set) {
    210 		wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: try_commit encrypt=%d",
    211 			   drv->ifname, drv->encrypt);
    212 		rtnl_link_macsec_set_encrypt(drv->link, drv->encrypt);
    213 	}
    214 
    215 	if (drv->replay_protect_set) {
    216 		wpa_printf(MSG_DEBUG, DRV_PREFIX
    217 			   "%s: try_commit replay_protect=%d replay_window=%d",
    218 			   drv->ifname, drv->replay_protect,
    219 			   drv->replay_window);
    220 		rtnl_link_macsec_set_replay_protect(drv->link,
    221 						    drv->replay_protect);
    222 		if (drv->replay_protect)
    223 			rtnl_link_macsec_set_window(drv->link,
    224 						    drv->replay_window);
    225 	}
    226 
    227 	if (drv->encoding_sa_set) {
    228 		wpa_printf(MSG_DEBUG, DRV_PREFIX
    229 			   "%s: try_commit encoding_sa=%d",
    230 			   drv->ifname, drv->encoding_sa);
    231 		rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa);
    232 	}
    233 
    234 	err = rtnl_link_add(drv->sk, drv->link, 0);
    235 	if (err < 0)
    236 		return err;
    237 
    238 	drv->protect_frames_set = FALSE;
    239 	drv->encrypt_set = FALSE;
    240 	drv->replay_protect_set = FALSE;
    241 
    242 	return 0;
    243 }
    244 
    245 
    246 static void macsec_drv_wpa_deinit(void *priv)
    247 {
    248 	struct macsec_drv_data *drv = priv;
    249 
    250 	driver_wired_deinit_common(&drv->common);
    251 	os_free(drv);
    252 }
    253 
    254 
    255 static int macsec_check_macsec(void)
    256 {
    257 	struct nl_sock *sk;
    258 	int err = -1;
    259 
    260 	sk = nl_socket_alloc();
    261 	if (!sk) {
    262 		wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
    263 		return -1;
    264 	}
    265 
    266 	if (genl_connect(sk) < 0) {
    267 		wpa_printf(MSG_ERROR,
    268 			   DRV_PREFIX "connection to genl socket failed");
    269 		goto out_free;
    270 	}
    271 
    272 	if (genl_ctrl_resolve(sk, "macsec") < 0) {
    273 		wpa_printf(MSG_ERROR,
    274 			   DRV_PREFIX "genl resolve failed - macsec kernel module not present?");
    275 		goto out_free;
    276 	}
    277 
    278 	err = 0;
    279 
    280 out_free:
    281 	nl_socket_free(sk);
    282 	return err;
    283 }
    284 
    285 
    286 static void * macsec_drv_wpa_init(void *ctx, const char *ifname)
    287 {
    288 	struct macsec_drv_data *drv;
    289 
    290 	if (macsec_check_macsec() < 0)
    291 		return NULL;
    292 
    293 	drv = os_zalloc(sizeof(*drv));
    294 	if (!drv)
    295 		return NULL;
    296 
    297 	if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
    298 		os_free(drv);
    299 		return NULL;
    300 	}
    301 
    302 	return drv;
    303 }
    304 
    305 
    306 static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params)
    307 {
    308 	struct macsec_drv_data *drv = priv;
    309 	int err;
    310 
    311 	wpa_printf(MSG_DEBUG, "%s", __func__);
    312 
    313 	drv->sk = nl_socket_alloc();
    314 	if (!drv->sk)
    315 		return -1;
    316 
    317 	err = nl_connect(drv->sk, NETLINK_ROUTE);
    318 	if (err < 0) {
    319 		wpa_printf(MSG_ERROR, DRV_PREFIX
    320 			   "Unable to connect NETLINK_ROUTE socket: %s",
    321 			   strerror(errno));
    322 		goto sock;
    323 	}
    324 
    325 	err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache);
    326 	if (err < 0) {
    327 		wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s",
    328 			   strerror(errno));
    329 		goto sock;
    330 	}
    331 
    332 	drv->parent_ifi = rtnl_link_name2i(drv->link_cache, drv->common.ifname);
    333 	if (drv->parent_ifi == 0) {
    334 		wpa_printf(MSG_ERROR, DRV_PREFIX
    335 			   "couldn't find ifindex for interface %s",
    336 			   drv->common.ifname);
    337 		goto cache;
    338 	}
    339 	wpa_printf(MSG_DEBUG, DRV_PREFIX "ifname=%s parent_ifi=%d",
    340 		   drv->common.ifname, drv->parent_ifi);
    341 
    342 	err = init_genl_ctx(drv);
    343 	if (err < 0)
    344 		goto cache;
    345 
    346 	return 0;
    347 
    348 cache:
    349 	nl_cache_free(drv->link_cache);
    350 	drv->link_cache = NULL;
    351 sock:
    352 	nl_socket_free(drv->sk);
    353 	drv->sk = NULL;
    354 	return -1;
    355 }
    356 
    357 
    358 static int macsec_drv_macsec_deinit(void *priv)
    359 {
    360 	struct macsec_drv_data *drv = priv;
    361 
    362 	wpa_printf(MSG_DEBUG, "%s", __func__);
    363 
    364 	if (drv->sk)
    365 		nl_socket_free(drv->sk);
    366 	drv->sk = NULL;
    367 
    368 	if (drv->link_cache)
    369 		nl_cache_free(drv->link_cache);
    370 	drv->link_cache = NULL;
    371 
    372 	if (drv->ctx.sk)
    373 		nl_socket_free(drv->ctx.sk);
    374 
    375 	return 0;
    376 }
    377 
    378 
    379 static int macsec_drv_get_capability(void *priv, enum macsec_cap *cap)
    380 {
    381 	wpa_printf(MSG_DEBUG, "%s", __func__);
    382 
    383 	*cap = MACSEC_CAP_INTEG_AND_CONF;
    384 
    385 	return 0;
    386 }
    387 
    388 
    389 /**
    390  * macsec_drv_enable_protect_frames - 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)
    395  */
    396 static int macsec_drv_enable_protect_frames(void *priv, Boolean enabled)
    397 {
    398 	struct macsec_drv_data *drv = priv;
    399 
    400 	wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
    401 
    402 	drv->protect_frames_set = TRUE;
    403 	drv->protect_frames = enabled;
    404 
    405 	return try_commit(drv);
    406 }
    407 
    408 
    409 /**
    410  * macsec_drv_enable_encrypt - Set protect frames status
    411  * @priv: Private driver interface data
    412  * @enabled: TRUE = protect frames enabled
    413  *           FALSE = protect frames disabled
    414  * Returns: 0 on success, -1 on failure (or if not supported)
    415  */
    416 static int macsec_drv_enable_encrypt(void *priv, Boolean enabled)
    417 {
    418 	struct macsec_drv_data *drv = priv;
    419 
    420 	wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
    421 
    422 	drv->encrypt_set = TRUE;
    423 	drv->encrypt = enabled;
    424 
    425 	return try_commit(drv);
    426 }
    427 
    428 
    429 /**
    430  * macsec_drv_set_replay_protect - Set replay protect status and window size
    431  * @priv: Private driver interface data
    432  * @enabled: TRUE = replay protect enabled
    433  *           FALSE = replay protect disabled
    434  * @window: replay window size, valid only when replay protect enabled
    435  * Returns: 0 on success, -1 on failure (or if not supported)
    436  */
    437 static int macsec_drv_set_replay_protect(void *priv, Boolean enabled,
    438 					 u32 window)
    439 {
    440 	struct macsec_drv_data *drv = priv;
    441 
    442 	wpa_printf(MSG_DEBUG, "%s -> %s, %u", __func__,
    443 		   enabled ? "TRUE" : "FALSE", window);
    444 
    445 	drv->replay_protect_set = TRUE;
    446 	drv->replay_protect = enabled;
    447 	if (enabled)
    448 		drv->replay_window = window;
    449 
    450 	return try_commit(drv);
    451 }
    452 
    453 
    454 /**
    455  * macsec_drv_set_current_cipher_suite - Set current cipher suite
    456  * @priv: Private driver interface data
    457  * @cs: EUI64 identifier
    458  * Returns: 0 on success, -1 on failure (or if not supported)
    459  */
    460 static int macsec_drv_set_current_cipher_suite(void *priv, u64 cs)
    461 {
    462 	wpa_printf(MSG_DEBUG, "%s -> %016" PRIx64, __func__, cs);
    463 	return 0;
    464 }
    465 
    466 
    467 /**
    468  * macsec_drv_enable_controlled_port - Set controlled port status
    469  * @priv: Private driver interface data
    470  * @enabled: TRUE = controlled port enabled
    471  *           FALSE = controlled port disabled
    472  * Returns: 0 on success, -1 on failure (or if not supported)
    473  */
    474 static int macsec_drv_enable_controlled_port(void *priv, Boolean enabled)
    475 {
    476 	struct macsec_drv_data *drv = priv;
    477 
    478 	wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
    479 
    480 	drv->controlled_port_enabled = enabled;
    481 	drv->controlled_port_enabled_set = TRUE;
    482 
    483 	return try_commit(drv);
    484 }
    485 
    486 
    487 static struct nla_policy sa_policy[MACSEC_SA_ATTR_MAX + 1] = {
    488 	[MACSEC_SA_ATTR_AN] = { .type = NLA_U8 },
    489 	[MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 },
    490 	[MACSEC_SA_ATTR_PN] = { .type = NLA_U32 },
    491 	[MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY },
    492 };
    493 
    494 static struct nla_policy sc_policy[MACSEC_RXSC_ATTR_MAX + 1] = {
    495 	[MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 },
    496 	[MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 },
    497 	[MACSEC_RXSC_ATTR_SA_LIST] = { .type = NLA_NESTED },
    498 };
    499 
    500 static struct nla_policy main_policy[MACSEC_ATTR_MAX + 1] = {
    501 	[MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 },
    502 	[MACSEC_ATTR_SECY] = { .type = NLA_NESTED },
    503 	[MACSEC_ATTR_TXSA_LIST] = { .type = NLA_NESTED },
    504 	[MACSEC_ATTR_RXSC_LIST] = { .type = NLA_NESTED },
    505 };
    506 
    507 static int dump_callback(struct nl_msg *msg, void *argp)
    508 {
    509 	struct nlmsghdr *ret_hdr = nlmsg_hdr(msg);
    510 	struct nlattr *tb_msg[MACSEC_ATTR_MAX + 1];
    511 	struct cb_arg *arg = (struct cb_arg *) argp;
    512 	struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(ret_hdr);
    513 	int err;
    514 
    515 	if (ret_hdr->nlmsg_type != arg->drv->ctx.macsec_genl_id)
    516 		return 0;
    517 
    518 	err = nla_parse(tb_msg, MACSEC_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    519 			genlmsg_attrlen(gnlh, 0), main_policy);
    520 	if (err < 0)
    521 		return 0;
    522 
    523 	if (!tb_msg[MACSEC_ATTR_IFINDEX])
    524 		return 0;
    525 
    526 	if (nla_get_u32(tb_msg[MACSEC_ATTR_IFINDEX]) != (u32) arg->ifindex)
    527 		return 0;
    528 
    529 	if (arg->txsa < 4 && !tb_msg[MACSEC_ATTR_TXSA_LIST]) {
    530 		return 0;
    531 	} else if (arg->txsa < 4) {
    532 		struct nlattr *nla;
    533 		int rem;
    534 
    535 		nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_TXSA_LIST], rem) {
    536 			struct nlattr *tb[MACSEC_SA_ATTR_MAX + 1];
    537 
    538 			err = nla_parse_nested(tb, MACSEC_SA_ATTR_MAX, nla,
    539 					       sa_policy);
    540 			if (err < 0)
    541 				continue;
    542 			if (!tb[MACSEC_SA_ATTR_AN])
    543 				continue;
    544 			if (nla_get_u8(tb[MACSEC_SA_ATTR_AN]) != arg->txsa)
    545 				continue;
    546 			if (!tb[MACSEC_SA_ATTR_PN])
    547 				return 0;
    548 			*arg->pn = nla_get_u32(tb[MACSEC_SA_ATTR_PN]);
    549 			return 0;
    550 		}
    551 
    552 		return 0;
    553 	}
    554 
    555 	if (arg->rxsci == UNUSED_SCI)
    556 		return 0;
    557 
    558 	if (tb_msg[MACSEC_ATTR_RXSC_LIST]) {
    559 		struct nlattr *nla;
    560 		int rem;
    561 
    562 		nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_RXSC_LIST], rem) {
    563 			struct nlattr *tb[MACSEC_RXSC_ATTR_MAX + 1];
    564 
    565 			err = nla_parse_nested(tb, MACSEC_RXSC_ATTR_MAX, nla,
    566 					       sc_policy);
    567 			if (err < 0)
    568 				return 0;
    569 			if (!tb[MACSEC_RXSC_ATTR_SCI])
    570 				continue;
    571 			if (nla_get_u64(tb[MACSEC_RXSC_ATTR_SCI]) != arg->rxsci)
    572 				continue;
    573 			if (!tb[MACSEC_RXSC_ATTR_SA_LIST])
    574 				return 0;
    575 
    576 			nla_for_each_nested(nla, tb[MACSEC_RXSC_ATTR_SA_LIST],
    577 					    rem) {
    578 				struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
    579 
    580 				err = nla_parse_nested(tb_sa,
    581 						       MACSEC_SA_ATTR_MAX, nla,
    582 						       sa_policy);
    583 				if (err < 0)
    584 					continue;
    585 				if (!tb_sa[MACSEC_SA_ATTR_AN])
    586 					continue;
    587 				if (nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]) !=
    588 				    arg->rxsa)
    589 					continue;
    590 				if (!tb_sa[MACSEC_SA_ATTR_PN])
    591 					return 0;
    592 				*arg->pn =
    593 					nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
    594 
    595 				return 0;
    596 			}
    597 
    598 			return 0;
    599 		}
    600 
    601 		return 0;
    602 	}
    603 
    604 	return 0;
    605 }
    606 
    607 
    608 static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg)
    609 {
    610 	int ret;
    611 
    612 	ret = nl_send_auto_complete(sk, msg);
    613 	if (ret < 0) {
    614 		wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to send: %d (%s)",
    615 			   __func__, ret, nl_geterror(-ret));
    616 		return ret;
    617 	}
    618 
    619 	ret = nl_recvmsgs_default(sk);
    620 	if (ret < 0) {
    621 		wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to recv: %d (%s)",
    622 			   __func__, ret, nl_geterror(-ret));
    623 	}
    624 
    625 	return ret;
    626 }
    627 
    628 
    629 static int do_dump(struct macsec_drv_data *drv, u8 txsa, u64 rxsci, u8 rxsa,
    630 		   u32 *pn)
    631 {
    632 	struct macsec_genl_ctx *ctx = &drv->ctx;
    633 	struct nl_msg *msg;
    634 	int ret = 1;
    635 
    636 	ctx->cb_arg.ifindex = drv->ifi;
    637 	ctx->cb_arg.rxsci = rxsci;
    638 	ctx->cb_arg.rxsa = rxsa;
    639 	ctx->cb_arg.txsa = txsa;
    640 	ctx->cb_arg.pn = pn;
    641 
    642 	msg = nlmsg_alloc();
    643 	if (!msg) {
    644 		wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to alloc message",
    645 			   __func__);
    646 		return 1;
    647 	}
    648 
    649 	if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->macsec_genl_id, 0,
    650 			 NLM_F_DUMP, MACSEC_CMD_GET_TXSC, 0)) {
    651 		wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to put header",
    652 			   __func__);
    653 		goto out_free_msg;
    654 	}
    655 
    656 	ret = nl_send_recv(ctx->sk, msg);
    657 	if (ret < 0)
    658 		wpa_printf(MSG_ERROR,
    659 			   DRV_PREFIX "failed to communicate: %d (%s)",
    660 			   ret, nl_geterror(-ret));
    661 
    662 	ctx->cb_arg.pn = NULL;
    663 
    664 out_free_msg:
    665 	nlmsg_free(msg);
    666 	return ret;
    667 }
    668 
    669 
    670 /**
    671  * macsec_drv_get_receive_lowest_pn - Get receive lowest PN
    672  * @priv: Private driver interface data
    673  * @sa: secure association
    674  * Returns: 0 on success, -1 on failure (or if not supported)
    675  */
    676 static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
    677 {
    678 	struct macsec_drv_data *drv = priv;
    679 	int err;
    680 
    681 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s", __func__);
    682 
    683 	err = do_dump(drv, 0xff, mka_sci_u64(&sa->sc->sci), sa->an,
    684 		      &sa->lowest_pn);
    685 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: result %d", __func__,
    686 		   sa->lowest_pn);
    687 
    688 	return err;
    689 }
    690 
    691 
    692 /**
    693  * macsec_drv_set_receive_lowest_pn - Set receive lowest PN
    694  * @priv: Private driver interface data
    695  * @sa: secure association
    696  * Returns: 0 on success, -1 on failure (or if not supported)
    697  */
    698 static int macsec_drv_set_receive_lowest_pn(void *priv, struct receive_sa *sa)
    699 {
    700 	struct macsec_drv_data *drv = priv;
    701 	struct macsec_genl_ctx *ctx = &drv->ctx;
    702 	struct nl_msg *msg;
    703 	struct nlattr *nest;
    704 	int ret = -1;
    705 
    706 	wpa_printf(MSG_DEBUG,
    707 		   DRV_PREFIX "%s: set_receive_lowest_pn -> %d: %d",
    708 		   drv->ifname, sa->an, sa->next_pn);
    709 
    710 	msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, drv->ifi);
    711 	if (!msg)
    712 		return ret;
    713 
    714 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
    715 	if (!nest)
    716 		goto nla_put_failure;
    717 
    718 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
    719 	NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
    720 
    721 	nla_nest_end(msg, nest);
    722 
    723 	ret = nl_send_recv(ctx->sk, msg);
    724 	if (ret < 0) {
    725 		wpa_printf(MSG_ERROR,
    726 			   DRV_PREFIX "failed to communicate: %d (%s)",
    727 			   ret, nl_geterror(-ret));
    728 	}
    729 
    730 nla_put_failure:
    731 	nlmsg_free(msg);
    732 	return ret;
    733 }
    734 
    735 
    736 /**
    737  * macsec_drv_get_transmit_next_pn - Get transmit next PN
    738  * @priv: Private driver interface data
    739  * @sa: secure association
    740  * Returns: 0 on success, -1 on failure (or if not supported)
    741  */
    742 static int macsec_drv_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
    743 {
    744 	struct macsec_drv_data *drv = priv;
    745 	int err;
    746 
    747 	wpa_printf(MSG_DEBUG, "%s", __func__);
    748 
    749 	err = do_dump(drv, sa->an, UNUSED_SCI, 0xff, &sa->next_pn);
    750 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: err %d result %d", __func__, err,
    751 		   sa->next_pn);
    752 	return err;
    753 }
    754 
    755 
    756 /**
    757  * macsec_drv_set_transmit_next_pn - Set transmit next pn
    758  * @priv: Private driver interface data
    759  * @sa: secure association
    760  * Returns: 0 on success, -1 on failure (or if not supported)
    761  */
    762 static int macsec_drv_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
    763 {
    764 	struct macsec_drv_data *drv = priv;
    765 	struct macsec_genl_ctx *ctx = &drv->ctx;
    766 	struct nl_msg *msg;
    767 	struct nlattr *nest;
    768 	int ret = -1;
    769 
    770 	wpa_printf(MSG_DEBUG, "%s -> %d: %d", __func__, sa->an, sa->next_pn);
    771 
    772 	msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, drv->ifi);
    773 	if (!msg)
    774 		return ret;
    775 
    776 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
    777 	if (!nest)
    778 		goto nla_put_failure;
    779 
    780 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
    781 	NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
    782 
    783 	nla_nest_end(msg, nest);
    784 
    785 	ret = nl_send_recv(ctx->sk, msg);
    786 	if (ret < 0) {
    787 		wpa_printf(MSG_ERROR,
    788 			   DRV_PREFIX "failed to communicate: %d (%s)",
    789 			   ret, nl_geterror(-ret));
    790 	}
    791 
    792 nla_put_failure:
    793 	nlmsg_free(msg);
    794 	return ret;
    795 }
    796 
    797 
    798 #define SCISTR MACSTR "::%hx"
    799 #define SCI2STR(addr, port) MAC2STR(addr), htons(port)
    800 
    801 /**
    802  * macsec_drv_create_receive_sc - Create secure channel for receiving
    803  * @priv: Private driver interface data
    804  * @sc: secure channel
    805  * @sci_addr: secure channel identifier - address
    806  * @sci_port: secure channel identifier - port
    807  * @conf_offset: confidentiality offset (0, 30, or 50)
    808  * @validation: frame validation policy (0 = Disabled, 1 = Checked,
    809  *	2 = Strict)
    810  * Returns: 0 on success, -1 on failure (or if not supported)
    811  */
    812 static int macsec_drv_create_receive_sc(void *priv, struct receive_sc *sc,
    813 					unsigned int conf_offset,
    814 					int validation)
    815 {
    816 	struct macsec_drv_data *drv = priv;
    817 	struct macsec_genl_ctx *ctx = &drv->ctx;
    818 	struct nl_msg *msg;
    819 	int ret = -1;
    820 
    821 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: create_receive_sc -> " SCISTR
    822 		   " (conf_offset=%u validation=%d)",
    823 		   drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port),
    824 		   conf_offset, validation);
    825 
    826 	msg = msg_prepare(MACSEC_CMD_ADD_RXSC, ctx, drv->ifi);
    827 	if (!msg)
    828 		return ret;
    829 
    830 	if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
    831 		goto nla_put_failure;
    832 
    833 	ret = nl_send_recv(ctx->sk, msg);
    834 	if (ret < 0) {
    835 		wpa_printf(MSG_ERROR,
    836 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
    837 			   __func__, ret, nl_geterror(-ret));
    838 	}
    839 
    840 nla_put_failure:
    841 	nlmsg_free(msg);
    842 	return ret;
    843 }
    844 
    845 
    846 /**
    847  * macsec_drv_delete_receive_sc - Delete secure connection for receiving
    848  * @priv: private driver interface data from init()
    849  * @sc: secure channel
    850  * Returns: 0 on success, -1 on failure
    851  */
    852 static int macsec_drv_delete_receive_sc(void *priv, struct receive_sc *sc)
    853 {
    854 	struct macsec_drv_data *drv = priv;
    855 	struct macsec_genl_ctx *ctx = &drv->ctx;
    856 	struct nl_msg *msg;
    857 	int ret = -1;
    858 
    859 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_receive_sc -> " SCISTR,
    860 		   drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port));
    861 
    862 	msg = msg_prepare(MACSEC_CMD_DEL_RXSC, ctx, drv->ifi);
    863 	if (!msg)
    864 		return ret;
    865 
    866 	if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
    867 		goto nla_put_failure;
    868 
    869 	ret = nl_send_recv(ctx->sk, msg);
    870 	if (ret < 0) {
    871 		wpa_printf(MSG_ERROR,
    872 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
    873 			   __func__, ret, nl_geterror(-ret));
    874 	}
    875 
    876 nla_put_failure:
    877 	nlmsg_free(msg);
    878 	return ret;
    879 }
    880 
    881 
    882 /**
    883  * macsec_drv_create_receive_sa - Create secure association for receive
    884  * @priv: private driver interface data from init()
    885  * @sa: secure association
    886  * Returns: 0 on success, -1 on failure
    887  */
    888 static int macsec_drv_create_receive_sa(void *priv, struct receive_sa *sa)
    889 {
    890 	struct macsec_drv_data *drv = priv;
    891 	struct macsec_genl_ctx *ctx = &drv->ctx;
    892 	struct nl_msg *msg;
    893 	struct nlattr *nest;
    894 	int ret = -1;
    895 
    896 	wpa_printf(MSG_DEBUG,
    897 		   DRV_PREFIX "%s: create_receive_sa -> %d on " SCISTR
    898 		   " (enable_receive=%d next_pn=%u)",
    899 		   drv->ifname, sa->an,
    900 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port),
    901 		   sa->enable_receive, sa->next_pn);
    902 	wpa_hexdump(MSG_DEBUG, DRV_PREFIX "SA keyid",
    903 		    &sa->pkey->key_identifier,
    904 		    sizeof(sa->pkey->key_identifier));
    905 	wpa_hexdump_key(MSG_DEBUG, DRV_PREFIX "SA key",
    906 			sa->pkey->key, sa->pkey->key_len);
    907 
    908 	msg = msg_prepare(MACSEC_CMD_ADD_RXSA, ctx, drv->ifi);
    909 	if (!msg)
    910 		return ret;
    911 
    912 	if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
    913 		goto nla_put_failure;
    914 
    915 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
    916 	if (!nest)
    917 		goto nla_put_failure;
    918 
    919 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
    920 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_receive);
    921 	NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
    922 	NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
    923 		&sa->pkey->key_identifier);
    924 	NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
    925 
    926 	nla_nest_end(msg, nest);
    927 
    928 	ret = nl_send_recv(ctx->sk, msg);
    929 	if (ret < 0) {
    930 		wpa_printf(MSG_ERROR,
    931 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
    932 			   __func__, ret, nl_geterror(-ret));
    933 	}
    934 
    935 nla_put_failure:
    936 	nlmsg_free(msg);
    937 	return ret;
    938 }
    939 
    940 
    941 /**
    942  * macsec_drv_delete_receive_sa - Delete secure association for receive
    943  * @priv: private driver interface data from init()
    944  * @sa: secure association
    945  * Returns: 0 on success, -1 on failure
    946  */
    947 static int macsec_drv_delete_receive_sa(void *priv, struct receive_sa *sa)
    948 {
    949 	struct macsec_drv_data *drv = priv;
    950 	struct macsec_genl_ctx *ctx = &drv->ctx;
    951 	struct nl_msg *msg;
    952 	struct nlattr *nest;
    953 	int ret = -1;
    954 
    955 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_receive_sa -> %d on "
    956 		   SCISTR, drv->ifname, sa->an,
    957 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
    958 
    959 	msg = msg_prepare(MACSEC_CMD_DEL_RXSA, ctx, drv->ifi);
    960 	if (!msg)
    961 		return ret;
    962 
    963 	if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
    964 		goto nla_put_failure;
    965 
    966 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
    967 	if (!nest)
    968 		goto nla_put_failure;
    969 
    970 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
    971 
    972 	nla_nest_end(msg, nest);
    973 
    974 	ret = nl_send_recv(ctx->sk, msg);
    975 	if (ret < 0) {
    976 		wpa_printf(MSG_ERROR,
    977 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
    978 			   __func__, ret, nl_geterror(-ret));
    979 	}
    980 
    981 nla_put_failure:
    982 	nlmsg_free(msg);
    983 	return ret;
    984 }
    985 
    986 
    987 static int set_active_rx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
    988 			    u64 sci, unsigned char an, Boolean state)
    989 {
    990 	struct nl_msg *msg;
    991 	struct nlattr *nest;
    992 	int ret = -1;
    993 
    994 	msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, ifindex);
    995 	if (!msg)
    996 		return ret;
    997 
    998 	if (nla_put_rxsc_config(msg, sci))
    999 		goto nla_put_failure;
   1000 
   1001 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
   1002 	if (!nest)
   1003 		goto nla_put_failure;
   1004 
   1005 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
   1006 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
   1007 
   1008 	nla_nest_end(msg, nest);
   1009 
   1010 	ret = nl_send_recv(ctx->sk, msg);
   1011 	if (ret < 0)
   1012 		wpa_printf(MSG_ERROR,
   1013 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
   1014 			   __func__, ret, nl_geterror(-ret));
   1015 
   1016 nla_put_failure:
   1017 	nlmsg_free(msg);
   1018 	return ret;
   1019 }
   1020 
   1021 
   1022 /**
   1023  * macsec_drv_enable_receive_sa - Enable the SA for receive
   1024  * @priv: private driver interface data from init()
   1025  * @sa: secure association
   1026  * Returns: 0 on success, -1 on failure
   1027  */
   1028 static int macsec_drv_enable_receive_sa(void *priv, struct receive_sa *sa)
   1029 {
   1030 	struct macsec_drv_data *drv = priv;
   1031 	struct macsec_genl_ctx *ctx = &drv->ctx;
   1032 
   1033 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: enable_receive_sa -> %d on "
   1034 		   SCISTR, drv->ifname, sa->an,
   1035 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
   1036 
   1037 	return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
   1038 				sa->an, TRUE);
   1039 }
   1040 
   1041 
   1042 /**
   1043  * macsec_drv_disable_receive_sa - Disable SA for receive
   1044  * @priv: private driver interface data from init()
   1045  * @sa: secure association
   1046  * Returns: 0 on success, -1 on failure
   1047  */
   1048 static int macsec_drv_disable_receive_sa(void *priv, struct receive_sa *sa)
   1049 {
   1050 	struct macsec_drv_data *drv = priv;
   1051 	struct macsec_genl_ctx *ctx = &drv->ctx;
   1052 
   1053 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: disable_receive_sa -> %d on "
   1054 		   SCISTR, drv->ifname, sa->an,
   1055 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
   1056 
   1057 	return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
   1058 				sa->an, FALSE);
   1059 }
   1060 
   1061 
   1062 static struct rtnl_link * lookup_sc(struct nl_cache *cache, int parent, u64 sci)
   1063 {
   1064 	struct rtnl_link *needle;
   1065 	void *match;
   1066 
   1067 	needle = rtnl_link_macsec_alloc();
   1068 	if (!needle)
   1069 		return NULL;
   1070 
   1071 	rtnl_link_set_link(needle, parent);
   1072 	rtnl_link_macsec_set_sci(needle, sci);
   1073 
   1074 	match = nl_cache_find(cache, (struct nl_object *) needle);
   1075 	rtnl_link_put(needle);
   1076 
   1077 	return (struct rtnl_link *) match;
   1078 }
   1079 
   1080 
   1081 /**
   1082  * macsec_drv_create_transmit_sc - Create secure connection for transmit
   1083  * @priv: private driver interface data from init()
   1084  * @sc: secure channel
   1085  * @conf_offset: confidentiality offset
   1086  * Returns: 0 on success, -1 on failure
   1087  */
   1088 static int macsec_drv_create_transmit_sc(
   1089 	void *priv, struct transmit_sc *sc,
   1090 	unsigned int conf_offset)
   1091 {
   1092 	struct macsec_drv_data *drv = priv;
   1093 	struct rtnl_link *link;
   1094 	char *ifname;
   1095 	u64 sci;
   1096 	int err;
   1097 
   1098 	wpa_printf(MSG_DEBUG, DRV_PREFIX
   1099 		   "%s: create_transmit_sc -> " SCISTR " (conf_offset=%d)",
   1100 		   drv->common.ifname, SCI2STR(sc->sci.addr, sc->sci.port),
   1101 		   conf_offset);
   1102 
   1103 	if (!drv->sk) {
   1104 		wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket");
   1105 		return -1;
   1106 	}
   1107 
   1108 	link = rtnl_link_macsec_alloc();
   1109 	if (!link) {
   1110 		wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
   1111 		return -1;
   1112 	}
   1113 
   1114 	rtnl_link_set_link(link, drv->parent_ifi);
   1115 
   1116 	sci = mka_sci_u64(&sc->sci);
   1117 	rtnl_link_macsec_set_sci(link, sci);
   1118 
   1119 	drv->created_link = TRUE;
   1120 
   1121 	err = rtnl_link_add(drv->sk, link, NLM_F_CREATE);
   1122 	if (err == -NLE_BUSY) {
   1123 		wpa_printf(MSG_INFO,
   1124 			   DRV_PREFIX "link already exists, using it");
   1125 		drv->created_link = FALSE;
   1126 	} else if (err < 0) {
   1127 		rtnl_link_put(link);
   1128 		wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't create link: err %d",
   1129 			   err);
   1130 		return err;
   1131 	}
   1132 
   1133 	rtnl_link_put(link);
   1134 
   1135 	nl_cache_refill(drv->sk, drv->link_cache);
   1136 	link = lookup_sc(drv->link_cache, drv->parent_ifi, sci);
   1137 	if (!link) {
   1138 		wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link");
   1139 		return -1;
   1140 	}
   1141 
   1142 	drv->ifi = rtnl_link_get_ifindex(link);
   1143 	ifname = rtnl_link_get_name(link);
   1144 	wpa_printf(MSG_DEBUG,
   1145 		   DRV_PREFIX "%s: create_transmit_sc: ifi=%d ifname=%s",
   1146 		   drv->common.ifname, drv->ifi, ifname);
   1147 	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
   1148 	rtnl_link_put(link);
   1149 
   1150 	drv->link = rtnl_link_macsec_alloc();
   1151 	if (!drv->link) {
   1152 		wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
   1153 		return -1;
   1154 	}
   1155 
   1156 	rtnl_link_set_name(drv->link, drv->ifname);
   1157 
   1158 	/* In case some settings have already been done but we couldn't apply
   1159 	 * them. */
   1160 	return try_commit(drv);
   1161 }
   1162 
   1163 
   1164 /**
   1165  * macsec_drv_delete_transmit_sc - Delete secure connection for transmit
   1166  * @priv: private driver interface data from init()
   1167  * @sc: secure channel
   1168  * Returns: 0 on success, -1 on failure
   1169  */
   1170 static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc)
   1171 {
   1172 	struct macsec_drv_data *drv = priv;
   1173 	int err;
   1174 
   1175 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_transmit_sc -> " SCISTR,
   1176 		   drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port));
   1177 
   1178 	if (!drv->sk)
   1179 		return 0;
   1180 
   1181 	if (!drv->created_link) {
   1182 		rtnl_link_put(drv->link);
   1183 		drv->link = NULL;
   1184 		wpa_printf(MSG_DEBUG, DRV_PREFIX
   1185 			   "we didn't create the link, leave it alone");
   1186 		return 0;
   1187 	}
   1188 
   1189 	err = rtnl_link_delete(drv->sk, drv->link);
   1190 	if (err < 0)
   1191 		wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link");
   1192 	rtnl_link_put(drv->link);
   1193 	drv->link = NULL;
   1194 
   1195 	return err;
   1196 }
   1197 
   1198 
   1199 /**
   1200  * macsec_drv_create_transmit_sa - Create secure association for transmit
   1201  * @priv: private driver interface data from init()
   1202  * @sa: secure association
   1203  * Returns: 0 on success, -1 on failure
   1204  */
   1205 static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa)
   1206 {
   1207 	struct macsec_drv_data *drv = priv;
   1208 	struct macsec_genl_ctx *ctx = &drv->ctx;
   1209 	struct nl_msg *msg;
   1210 	struct nlattr *nest;
   1211 	int ret = -1;
   1212 
   1213 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: create_transmit_sa -> %d on "
   1214 		   SCISTR " (enable_transmit=%d next_pn=%u)",
   1215 		   drv->ifname, sa->an,
   1216 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port),
   1217 		   sa->enable_transmit, sa->next_pn);
   1218 	wpa_hexdump(MSG_DEBUG, DRV_PREFIX "SA keyid",
   1219 		    &sa->pkey->key_identifier,
   1220 		    sizeof(sa->pkey->key_identifier));
   1221 	wpa_hexdump_key(MSG_DEBUG, DRV_PREFIX "SA key",
   1222 			sa->pkey->key, sa->pkey->key_len);
   1223 
   1224 	msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi);
   1225 	if (!msg)
   1226 		return ret;
   1227 
   1228 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
   1229 	if (!nest)
   1230 		goto nla_put_failure;
   1231 
   1232 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
   1233 	NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
   1234 	NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
   1235 		&sa->pkey->key_identifier);
   1236 	NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
   1237 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit);
   1238 
   1239 	nla_nest_end(msg, nest);
   1240 
   1241 	ret = nl_send_recv(ctx->sk, msg);
   1242 	if (ret < 0) {
   1243 		wpa_printf(MSG_ERROR,
   1244 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
   1245 			   __func__, ret, nl_geterror(-ret));
   1246 	}
   1247 
   1248 nla_put_failure:
   1249 	nlmsg_free(msg);
   1250 	return ret;
   1251 }
   1252 
   1253 
   1254 /**
   1255  * macsec_drv_delete_transmit_sa - Delete secure association for transmit
   1256  * @priv: private driver interface data from init()
   1257  * @sa: secure association
   1258  * Returns: 0 on success, -1 on failure
   1259  */
   1260 static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa)
   1261 {
   1262 	struct macsec_drv_data *drv = priv;
   1263 	struct macsec_genl_ctx *ctx = &drv->ctx;
   1264 	struct nl_msg *msg;
   1265 	struct nlattr *nest;
   1266 	int ret = -1;
   1267 
   1268 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_transmit_sa -> %d on "
   1269 		   SCISTR, drv->ifname, sa->an,
   1270 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
   1271 
   1272 	msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi);
   1273 	if (!msg)
   1274 		return ret;
   1275 
   1276 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
   1277 	if (!nest)
   1278 		goto nla_put_failure;
   1279 
   1280 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
   1281 
   1282 	nla_nest_end(msg, nest);
   1283 
   1284 	ret = nl_send_recv(ctx->sk, msg);
   1285 	if (ret < 0) {
   1286 		wpa_printf(MSG_ERROR,
   1287 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
   1288 			   __func__, ret, nl_geterror(-ret));
   1289 	}
   1290 
   1291 nla_put_failure:
   1292 	nlmsg_free(msg);
   1293 	return ret;
   1294 }
   1295 
   1296 
   1297 static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
   1298 			    unsigned char an, Boolean state)
   1299 {
   1300 	struct nl_msg *msg;
   1301 	struct nlattr *nest;
   1302 	int ret = -1;
   1303 
   1304 	msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex);
   1305 	if (!msg)
   1306 		return ret;
   1307 
   1308 	nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
   1309 	if (!nest)
   1310 		goto nla_put_failure;
   1311 
   1312 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
   1313 	NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
   1314 
   1315 	nla_nest_end(msg, nest);
   1316 
   1317 	ret = nl_send_recv(ctx->sk, msg);
   1318 	if (ret < 0) {
   1319 		wpa_printf(MSG_ERROR,
   1320 			   DRV_PREFIX "%s: failed to communicate: %d (%s)",
   1321 			   __func__, ret, nl_geterror(-ret));
   1322 	}
   1323 
   1324 nla_put_failure:
   1325 	nlmsg_free(msg);
   1326 	return ret;
   1327 }
   1328 
   1329 
   1330 /**
   1331  * macsec_drv_enable_transmit_sa - Enable SA for transmit
   1332  * @priv: private driver interface data from init()
   1333  * @sa: secure association
   1334  * Returns: 0 on success, -1 on failure
   1335  */
   1336 static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa)
   1337 {
   1338 	struct macsec_drv_data *drv = priv;
   1339 	struct macsec_genl_ctx *ctx = &drv->ctx;
   1340 	int ret;
   1341 
   1342 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: enable_transmit_sa -> %d on "
   1343 		   SCISTR, drv->ifname, sa->an,
   1344 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
   1345 
   1346 	ret = set_active_tx_sa(ctx, drv->ifi, sa->an, TRUE);
   1347 	if (ret < 0) {
   1348 		wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa");
   1349 		return ret;
   1350 	}
   1351 
   1352 	drv->encoding_sa_set = TRUE;
   1353 	drv->encoding_sa = sa->an;
   1354 
   1355 	return try_commit(drv);
   1356 }
   1357 
   1358 
   1359 /**
   1360  * macsec_drv_disable_transmit_sa - Disable SA for transmit
   1361  * @priv: private driver interface data from init()
   1362  * @sa: secure association
   1363  * Returns: 0 on success, -1 on failure
   1364  */
   1365 static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa)
   1366 {
   1367 	struct macsec_drv_data *drv = priv;
   1368 	struct macsec_genl_ctx *ctx = &drv->ctx;
   1369 
   1370 	wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: disable_transmit_sa -> %d on "
   1371 		   SCISTR, drv->ifname, sa->an,
   1372 		   SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
   1373 
   1374 	return set_active_tx_sa(ctx, drv->ifi, sa->an, FALSE);
   1375 }
   1376 
   1377 
   1378 static int macsec_drv_status(void *priv, char *buf, size_t buflen)
   1379 {
   1380 	struct macsec_drv_data *drv = priv;
   1381 	int res;
   1382 	char *pos, *end;
   1383 
   1384 	pos = buf;
   1385 	end = buf + buflen;
   1386 
   1387 	res = os_snprintf(pos, end - pos,
   1388 			  "ifname=%s\n"
   1389 			  "ifi=%d\n"
   1390 			  "parent_ifname=%s\n"
   1391 			  "parent_ifi=%d\n",
   1392 			  drv->common.ifname, drv->ifi,
   1393 			  drv->ifname, drv->parent_ifi);
   1394 	if (os_snprintf_error(end - pos, res))
   1395 		return pos - buf;
   1396 	pos += res;
   1397 
   1398 	return pos - buf;
   1399 }
   1400 
   1401 
   1402 const struct wpa_driver_ops wpa_driver_macsec_linux_ops = {
   1403 	.name = "macsec_linux",
   1404 	.desc = "MACsec Ethernet driver for Linux",
   1405 	.get_ssid = driver_wired_get_ssid,
   1406 	.get_bssid = driver_wired_get_bssid,
   1407 	.get_capa = driver_wired_get_capa,
   1408 	.init = macsec_drv_wpa_init,
   1409 	.deinit = macsec_drv_wpa_deinit,
   1410 
   1411 	.macsec_init = macsec_drv_macsec_init,
   1412 	.macsec_deinit = macsec_drv_macsec_deinit,
   1413 	.macsec_get_capability = macsec_drv_get_capability,
   1414 	.enable_protect_frames = macsec_drv_enable_protect_frames,
   1415 	.enable_encrypt = macsec_drv_enable_encrypt,
   1416 	.set_replay_protect = macsec_drv_set_replay_protect,
   1417 	.set_current_cipher_suite = macsec_drv_set_current_cipher_suite,
   1418 	.enable_controlled_port = macsec_drv_enable_controlled_port,
   1419 	.get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn,
   1420 	.set_receive_lowest_pn = macsec_drv_set_receive_lowest_pn,
   1421 	.get_transmit_next_pn = macsec_drv_get_transmit_next_pn,
   1422 	.set_transmit_next_pn = macsec_drv_set_transmit_next_pn,
   1423 	.create_receive_sc = macsec_drv_create_receive_sc,
   1424 	.delete_receive_sc = macsec_drv_delete_receive_sc,
   1425 	.create_receive_sa = macsec_drv_create_receive_sa,
   1426 	.delete_receive_sa = macsec_drv_delete_receive_sa,
   1427 	.enable_receive_sa = macsec_drv_enable_receive_sa,
   1428 	.disable_receive_sa = macsec_drv_disable_receive_sa,
   1429 	.create_transmit_sc = macsec_drv_create_transmit_sc,
   1430 	.delete_transmit_sc = macsec_drv_delete_transmit_sc,
   1431 	.create_transmit_sa = macsec_drv_create_transmit_sa,
   1432 	.delete_transmit_sa = macsec_drv_delete_transmit_sa,
   1433 	.enable_transmit_sa = macsec_drv_enable_transmit_sa,
   1434 	.disable_transmit_sa = macsec_drv_disable_transmit_sa,
   1435 
   1436 	.status = macsec_drv_status,
   1437 };
   1438