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