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