1 /* 2 * Driver interaction with Linux MACsec kernel module 3 * Copyright (c) 2016, Sabrina Dubroca <sd@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