libnl  3.2.29
macsec.c
1 /*
2  * lib/route/link/macsec.c MACsec Link Info
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2016 Sabrina Dubroca <sd@queasysnail.net>
10  */
11 
12 /**
13  * @ingroup link
14  * @defgroup macsec MACsec
15  * MACsec link module
16  *
17  * @details
18  * \b Link Type Name: "macsec"
19  *
20  * @route_doc{link_macsec, MACsec Documentation}
21  *
22  * @{
23  */
24 #include <netlink-private/netlink.h>
25 #include <netlink/netlink.h>
26 #include <netlink/attr.h>
27 #include <netlink/utils.h>
28 #include <netlink/object.h>
29 #include <netlink/route/rtnl.h>
30 #include <netlink-private/route/link/api.h>
31 #include <netlink-private/utils.h>
32 
33 #include <linux/if_macsec.h>
34 
35 /** @cond SKIP */
36 #define MACSEC_ATTR_SCI (1 << 0)
37 #define MACSEC_ATTR_ICV_LEN (1 << 1)
38 #define MACSEC_ATTR_CIPHER_SUITE (1 << 2)
39 #define MACSEC_ATTR_WINDOW (1 << 3)
40 #define MACSEC_ATTR_ENCODING_SA (1 << 4)
41 #define MACSEC_ATTR_ENCRYPT (1 << 5)
42 #define MACSEC_ATTR_PROTECT (1 << 6)
43 #define MACSEC_ATTR_INC_SCI (1 << 7)
44 #define MACSEC_ATTR_ES (1 << 8)
45 #define MACSEC_ATTR_SCB (1 << 9)
46 #define MACSEC_ATTR_REPLAY_PROTECT (1 << 10)
47 #define MACSEC_ATTR_VALIDATION (1 << 11)
48 #define MACSEC_ATTR_PORT (1 << 12)
49 
50 struct macsec_info {
51  int ifindex;
52  uint64_t sci;
53  uint16_t port;
54  uint64_t cipher_suite;
55  uint16_t icv_len;
56  uint32_t window;
57  enum macsec_validation_type validate;
58  uint8_t encoding_sa;
59 
60  uint8_t send_sci, end_station, scb, replay_protect, protect, encrypt;
61 
62  uint32_t ce_mask;
63 };
64 
65 #define DEFAULT_ICV_LEN 16
66 
67 /** @endcond */
68 
69 static struct nla_policy macsec_policy[IFLA_MACSEC_MAX+1] = {
70  [IFLA_MACSEC_SCI] = { .type = NLA_U64 },
71  [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 },
72  [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 },
73  [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 },
74  [IFLA_MACSEC_ENCODING_SA] = { .type = NLA_U8 },
75  [IFLA_MACSEC_ENCRYPT] = { .type = NLA_U8 },
76  [IFLA_MACSEC_PROTECT] = { .type = NLA_U8 },
77  [IFLA_MACSEC_INC_SCI] = { .type = NLA_U8 },
78  [IFLA_MACSEC_ES] = { .type = NLA_U8 },
79  [IFLA_MACSEC_SCB] = { .type = NLA_U8 },
80  [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
81  [IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
82 };
83 
84 /**
85  * @name MACsec Object
86  * @{
87  */
88 
89 /**
90  * Allocate link object of type MACsec
91  *
92  * @return Allocated link object or NULL.
93  */
94 static int macsec_alloc(struct rtnl_link *link)
95 {
96  struct macsec_info *info;
97 
98  if (!link->l_info) {
99  link->l_info = malloc(sizeof(struct macsec_info));
100  if (!link->l_info)
101  return -NLE_NOMEM;
102  }
103 
104  memset(link->l_info, 0, sizeof(struct macsec_info));
105  info = link->l_info;
106 
107  info->cipher_suite = MACSEC_DEFAULT_CIPHER_ID;
108  info->icv_len = DEFAULT_ICV_LEN;
109  info->ce_mask = MACSEC_ATTR_CIPHER_SUITE | MACSEC_ATTR_ICV_LEN;
110 
111  return 0;
112 }
113 
114 static int macsec_parse(struct rtnl_link *link, struct nlattr *data,
115  struct nlattr *xstats)
116 {
117  struct nlattr *tb[IFLA_MACSEC_MAX+1];
118  struct macsec_info *info;
119  int err;
120 
121  NL_DBG(3, "Parsing MACsec link info\n");
122 
123  if ((err = nla_parse_nested(tb, IFLA_MACSEC_MAX, data, macsec_policy)) < 0)
124  goto errout;
125 
126  if ((err = macsec_alloc(link)) < 0)
127  goto errout;
128 
129  info = link->l_info;
130 
131  if (tb[IFLA_MACSEC_SCI]) {
132  info->sci = nla_get_u64(tb[IFLA_MACSEC_SCI]);
133  info->ce_mask |= MACSEC_ATTR_SCI;
134  }
135 
136  if (tb[IFLA_MACSEC_PROTECT]) {
137  info->protect = nla_get_u8(tb[IFLA_MACSEC_PROTECT]);
138  info->ce_mask |= MACSEC_ATTR_PROTECT;
139  }
140 
141  if (tb[IFLA_MACSEC_CIPHER_SUITE]) {
142  info->cipher_suite = nla_get_u64(tb[IFLA_MACSEC_CIPHER_SUITE]);
143  info->ce_mask |= MACSEC_ATTR_CIPHER_SUITE;
144  }
145 
146  if (tb[IFLA_MACSEC_ICV_LEN]) {
147  info->icv_len = nla_get_u8(tb[IFLA_MACSEC_ICV_LEN]);
148  info->ce_mask |= MACSEC_ATTR_ICV_LEN;
149  }
150 
151  if (tb[IFLA_MACSEC_ENCODING_SA]) {
152  info->encoding_sa = nla_get_u8(tb[IFLA_MACSEC_ENCODING_SA]);
153  info->ce_mask |= MACSEC_ATTR_ENCODING_SA;
154  }
155 
156  if (tb[IFLA_MACSEC_VALIDATION]) {
157  info->validate = nla_get_u8(tb[IFLA_MACSEC_VALIDATION]);
158  info->ce_mask |= MACSEC_ATTR_VALIDATION;
159  }
160 
161  if (tb[IFLA_MACSEC_ENCRYPT]) {
162  info->encrypt = nla_get_u8(tb[IFLA_MACSEC_ENCRYPT]);
163  info->ce_mask |= MACSEC_ATTR_ENCRYPT;
164  }
165 
166  if (tb[IFLA_MACSEC_INC_SCI]) {
167  info->send_sci = nla_get_u8(tb[IFLA_MACSEC_INC_SCI]);
168  info->ce_mask |= MACSEC_ATTR_INC_SCI;
169  }
170 
171  if (tb[IFLA_MACSEC_ES]) {
172  info->end_station = nla_get_u8(tb[IFLA_MACSEC_ES]);
173  info->ce_mask |= MACSEC_ATTR_ES;
174  }
175 
176  if (tb[IFLA_MACSEC_SCB]) {
177  info->scb = nla_get_u8(tb[IFLA_MACSEC_SCB]);
178  info->ce_mask |= MACSEC_ATTR_SCB;
179  }
180 
181  if (tb[IFLA_MACSEC_REPLAY_PROTECT]) {
182  info->replay_protect = nla_get_u8(tb[IFLA_MACSEC_REPLAY_PROTECT]);
183  info->ce_mask |= MACSEC_ATTR_REPLAY_PROTECT;
184  }
185 
186  if (tb[IFLA_MACSEC_WINDOW]) {
187  info->window = nla_get_u32(tb[IFLA_MACSEC_WINDOW]);
188  info->ce_mask |= MACSEC_ATTR_WINDOW;
189  }
190 
191  err = 0;
192 errout:
193  return err;
194 }
195 
196 static void macsec_free(struct rtnl_link *link)
197 {
198  free(link->l_info);
199  link->l_info = NULL;
200 }
201 
202 static const char *values_on_off[] = { "off", "on" };
203 
204 static const char *VALIDATE_STR[] = {
205  [MACSEC_VALIDATE_DISABLED] = "disabled",
206  [MACSEC_VALIDATE_CHECK] = "check",
207  [MACSEC_VALIDATE_STRICT] = "strict",
208 };
209 
210 static char *replay_protect_str(char *buf, uint8_t replay_protect, uint8_t window)
211 {
212  if (replay_protect == 1) {
213  sprintf(buf, "replay_protect on window %d", window);
214  } else if (replay_protect == 0) {
215  sprintf(buf, "replay_protect off");
216  } else {
217  buf[0] = '\0';
218  }
219 
220  return buf;
221 }
222 
223 /** @cond SKIP */
224 #define PRINT_FLAG(buf, i, field, c) ({ if (i->field == 1) *buf++ = c; })
225 /** @endcond */
226 static char *flags_str(char *buf, unsigned char len, struct macsec_info *info)
227 {
228  char *tmp = buf;
229  memset(tmp, 0, len);
230 
231  PRINT_FLAG(tmp, info, protect, 'P');
232  PRINT_FLAG(tmp, info, encrypt, 'E');
233  PRINT_FLAG(tmp, info, send_sci, 'S');
234  PRINT_FLAG(tmp, info, end_station, 'e');
235  PRINT_FLAG(tmp, info, scb, 's');
236  PRINT_FLAG(tmp, info, replay_protect, 'R');
237 
238  *tmp++ = ' ';
239  *tmp++ = 'v';
240  switch (info->validate) {
241  case MACSEC_VALIDATE_DISABLED:
242  *tmp++ = 'd';
243  break;
244  case MACSEC_VALIDATE_CHECK:
245  *tmp++ = 'c';
246  break;
247  case MACSEC_VALIDATE_STRICT:
248  *tmp++ = 's';
249  break;
250  default:
251  break;
252  }
253 
254  sprintf(tmp, " %d", info->encoding_sa);
255 
256  return buf;
257 }
258 
259 static void macsec_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
260 {
261  struct macsec_info *info = link->l_info;
262  char tmp[128];
263 
264  nl_dump(p, "sci %016llx <%s>", ntohll(info->sci), flags_str(tmp, sizeof(tmp), info));
265 }
266 
267 static void macsec_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
268 {
269  struct macsec_info *info = link->l_info;
270  char tmp[128];
271 
272  nl_dump(p, " sci %016llx protect %s encoding_sa %d encrypt %s send_sci %s validate %s %s\n",
273  ntohll(info->sci), values_on_off[info->protect], info->encoding_sa, values_on_off[info->encrypt], values_on_off[info->send_sci],
274  VALIDATE_STR[info->validate],
275  replay_protect_str(tmp, info->replay_protect, info->window));
276  nl_dump(p, " cipher suite: %016llx, icv_len %d\n",
277  info->cipher_suite, info->icv_len);
278 }
279 
280 static int macsec_clone(struct rtnl_link *dst, struct rtnl_link *src)
281 {
282  struct macsec_info *copy, *info = src->l_info;
283  int err;
284 
285  dst->l_info = NULL;
286  if ((err = rtnl_link_set_type(dst, "macsec")) < 0)
287  return err;
288  copy = dst->l_info;
289 
290  if (!info || !copy)
291  return -NLE_NOMEM;
292 
293  memcpy(copy, info, sizeof(struct macsec_info));
294 
295  return 0;
296 }
297 
298 static int macsec_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
299 {
300  struct macsec_info *info = link->l_info;
301  struct nlattr *data;
302 
303  if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
304  return -NLE_MSGSIZE;
305 
306  if (info->ce_mask & MACSEC_ATTR_SCI)
307  NLA_PUT_U64(msg, IFLA_MACSEC_SCI, info->sci);
308  else if (info->ce_mask & MACSEC_ATTR_PORT)
309  NLA_PUT_U16(msg, IFLA_MACSEC_PORT, htons(info->port));
310 
311  if ((info->ce_mask & MACSEC_ATTR_ENCRYPT))
312  NLA_PUT_U8(msg, IFLA_MACSEC_ENCRYPT, info->encrypt);
313 
314  if (info->cipher_suite != MACSEC_DEFAULT_CIPHER_ID || info->icv_len != DEFAULT_ICV_LEN) {
315  NLA_PUT_U64(msg, IFLA_MACSEC_CIPHER_SUITE, info->cipher_suite);
316  NLA_PUT_U8(msg, IFLA_MACSEC_ICV_LEN, info->icv_len);
317  }
318 
319  if ((info->ce_mask & MACSEC_ATTR_INC_SCI))
320  NLA_PUT_U8(msg, IFLA_MACSEC_INC_SCI, info->send_sci);
321 
322  if ((info->ce_mask & MACSEC_ATTR_ES))
323  NLA_PUT_U8(msg, IFLA_MACSEC_ES, info->end_station);
324 
325  if ((info->ce_mask & MACSEC_ATTR_SCB))
326  NLA_PUT_U8(msg, IFLA_MACSEC_SCB, info->scb);
327 
328  if ((info->ce_mask & MACSEC_ATTR_PROTECT))
329  NLA_PUT_U8(msg, IFLA_MACSEC_PROTECT, info->protect);
330 
331  if ((info->ce_mask & MACSEC_ATTR_REPLAY_PROTECT)) {
332  if (info->replay_protect && !(info->ce_mask & MACSEC_ATTR_WINDOW))
333  return -NLE_INVAL;
334 
335  NLA_PUT_U8(msg, IFLA_MACSEC_REPLAY_PROTECT, info->replay_protect);
336  NLA_PUT_U32(msg, IFLA_MACSEC_WINDOW, info->window);
337  }
338 
339  if ((info->ce_mask & MACSEC_ATTR_VALIDATION))
340  NLA_PUT_U8(msg, IFLA_MACSEC_VALIDATION, info->validate);
341 
342  if ((info->ce_mask & MACSEC_ATTR_ENCODING_SA))
343  NLA_PUT_U8(msg, IFLA_MACSEC_ENCODING_SA, info->encoding_sa);
344 
345  nla_nest_end(msg, data);
346 
347  return 0;
348 
349 nla_put_failure:
350  return -NLE_MSGSIZE;
351 }
352 
353 static int macsec_compare(struct rtnl_link *link_a, struct rtnl_link *link_b,
354  int flags)
355 {
356  struct macsec_info *a = link_a->l_info;
357  struct macsec_info *b = link_b->l_info;
358  int diff = 0;
359  uint32_t attrs = flags & LOOSE_COMPARISON ? b->ce_mask : ~0;
360 
361 #define MACSEC_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MACSEC_ATTR_##ATTR, a, b, EXPR)
362 
363  if (a->ce_mask & MACSEC_ATTR_SCI && b->ce_mask & MACSEC_ATTR_SCI)
364  diff |= MACSEC_DIFF(SCI, a->sci != b->sci);
365  else if (a->ce_mask & MACSEC_ATTR_PORT && b->ce_mask & MACSEC_ATTR_PORT)
366  diff |= MACSEC_DIFF(PORT, a->port != b->port);
367 
368  if (a->ce_mask & MACSEC_ATTR_CIPHER_SUITE && b->ce_mask & MACSEC_ATTR_CIPHER_SUITE) {
369  diff |= MACSEC_DIFF(ICV_LEN, a->icv_len != b->icv_len);
370  diff |= MACSEC_DIFF(CIPHER_SUITE, a->cipher_suite != b->cipher_suite);
371  }
372 
373  if (a->ce_mask & MACSEC_ATTR_REPLAY_PROTECT && b->ce_mask & MACSEC_ATTR_REPLAY_PROTECT) {
374  int d = MACSEC_DIFF(REPLAY_PROTECT, a->replay_protect != b->replay_protect);
375  if (a->replay_protect && b->replay_protect)
376  d |= MACSEC_DIFF(WINDOW, a->window != b->window);
377  diff |= d;
378  }
379 
380  diff |= MACSEC_DIFF(ENCODING_SA, a->encoding_sa != b->encoding_sa);
381  diff |= MACSEC_DIFF(ENCRYPT, a->encrypt != b->encrypt);
382  diff |= MACSEC_DIFF(PROTECT, a->protect != b->protect);
383  diff |= MACSEC_DIFF(INC_SCI, a->send_sci != b->send_sci);
384  diff |= MACSEC_DIFF(ES, a->end_station != b->end_station);
385  diff |= MACSEC_DIFF(SCB, a->scb != b->scb);
386  diff |= MACSEC_DIFF(VALIDATION, a->validate != b->validate);
387 #undef MACSEC_DIFF
388 
389  return diff;
390 }
391 
392 
393 static struct rtnl_link_info_ops macsec_info_ops = {
394  .io_name = "macsec",
395  .io_alloc = macsec_alloc,
396  .io_parse = macsec_parse,
397  .io_dump = {
398  [NL_DUMP_LINE] = macsec_dump_line,
399  [NL_DUMP_DETAILS] = macsec_dump_details,
400  },
401  .io_clone = macsec_clone,
402  .io_put_attrs = macsec_put_attrs,
403  .io_free = macsec_free,
404  .io_compare = macsec_compare,
405 };
406 
407 static void __init macsec_init(void)
408 {
409  rtnl_link_register_info(&macsec_info_ops);
410 }
411 
412 static void __exit macsec_exit(void)
413 {
414  rtnl_link_unregister_info(&macsec_info_ops);
415 }
416 
417 /** @cond SKIP */
418 #define IS_MACSEC_LINK_ASSERT(link) \
419  if ((link)->l_info_ops != &macsec_info_ops) { \
420  APPBUG("Link is not a MACsec link. set type \"macsec\" first."); \
421  return -NLE_OPNOTSUPP; \
422  }
423 /** @endcond */
424 
425 struct rtnl_link *rtnl_link_macsec_alloc(void)
426 {
427  struct rtnl_link *link = rtnl_link_alloc();
428 
429  if (!link)
430  return NULL;
431 
432  if (rtnl_link_set_type(link, "macsec") < 0) {
433  rtnl_link_put(link);
434  return NULL;
435  }
436 
437  return link;
438 }
439 
440 /**
441  * Set SCI
442  * @arg link Link object
443  * @arg sci Secure Channel Identifier in network byte order
444  *
445  * @return 0 on success or a negative error code.
446  */
447 int rtnl_link_macsec_set_sci(struct rtnl_link *link, uint64_t sci)
448 {
449  struct macsec_info *info = link->l_info;
450 
451  IS_MACSEC_LINK_ASSERT(link);
452 
453  info->sci = sci;
454  info->ce_mask |= MACSEC_ATTR_SCI;
455 
456  return 0;
457 }
458 
459 /**
460  * Get SCI
461  * @arg link Link object
462  * @arg sci On return points to the Secure Channel Identifier
463  * in network byte order
464  *
465  * @return 0 on success or a negative error code.
466  */
467 int rtnl_link_macsec_get_sci(struct rtnl_link *link, uint64_t *sci)
468 {
469  struct macsec_info *info = link->l_info;
470 
471  IS_MACSEC_LINK_ASSERT(link);
472 
473  if (!(info->ce_mask & MACSEC_ATTR_SCI))
474  return -NLE_NOATTR;
475 
476  if (sci)
477  *sci = info->sci;
478 
479  return 0;
480 }
481 
482 /**
483  * Set port identifier
484  * @arg link Link object
485  * @arg port Port identifier in host byte order
486  *
487  * @return 0 on success or a negative error code.
488  */
489 int rtnl_link_macsec_set_port(struct rtnl_link *link, uint16_t port)
490 {
491  struct macsec_info *info = link->l_info;
492 
493  IS_MACSEC_LINK_ASSERT(link);
494 
495  info->port = port;
496  info->ce_mask |= MACSEC_ATTR_PORT;
497 
498  return 0;
499 }
500 
501 /**
502  * Get port identifier
503  * @arg link Link object
504  * @arg port On return points to the port identifier in host byte order
505  *
506  * @return 0 on success or a negative error code.
507  */
508 int rtnl_link_macsec_get_port(struct rtnl_link *link, uint16_t *port)
509 {
510  struct macsec_info *info = link->l_info;
511 
512  IS_MACSEC_LINK_ASSERT(link);
513 
514  if (!(info->ce_mask & MACSEC_ATTR_PORT))
515  return -NLE_NOATTR;
516 
517  if (port)
518  *port = info->port;
519 
520  return 0;
521 }
522 
523 int rtnl_link_macsec_set_cipher_suite(struct rtnl_link *link, uint64_t cipher_suite)
524 {
525  struct macsec_info *info = link->l_info;
526 
527  IS_MACSEC_LINK_ASSERT(link);
528 
529  info->cipher_suite = cipher_suite;
530  info->ce_mask |= MACSEC_ATTR_CIPHER_SUITE;
531 
532  return 0;
533 }
534 
535 int rtnl_link_macsec_get_cipher_suite(struct rtnl_link *link, uint64_t *cs)
536 {
537  struct macsec_info *info = link->l_info;
538 
539  IS_MACSEC_LINK_ASSERT(link);
540 
541  if (!(info->ce_mask & MACSEC_ATTR_CIPHER_SUITE))
542  return -NLE_NOATTR;
543 
544  if (cs)
545  *cs = info->cipher_suite;
546 
547  return 0;
548 }
549 
550 int rtnl_link_macsec_set_icv_len(struct rtnl_link *link, uint16_t icv_len)
551 {
552  struct macsec_info *info = link->l_info;
553 
554  IS_MACSEC_LINK_ASSERT(link);
555 
556  if (icv_len > MACSEC_STD_ICV_LEN)
557  return -NLE_INVAL;
558 
559  info->icv_len = icv_len;
560  info->ce_mask |= MACSEC_ATTR_ICV_LEN;
561 
562  return 0;
563 }
564 
565 int rtnl_link_macsec_get_icv_len(struct rtnl_link *link, uint16_t *icv_len)
566 {
567  struct macsec_info *info = link->l_info;
568 
569  IS_MACSEC_LINK_ASSERT(link);
570 
571  if (!(info->ce_mask & MACSEC_ATTR_ICV_LEN))
572  return -NLE_NOATTR;
573 
574  if (icv_len)
575  *icv_len = info->icv_len;
576 
577  return 0;
578 }
579 
580 int rtnl_link_macsec_set_protect(struct rtnl_link *link, uint8_t protect)
581 {
582  struct macsec_info *info = link->l_info;
583 
584  IS_MACSEC_LINK_ASSERT(link);
585 
586  if (protect > 1)
587  return -NLE_INVAL;
588 
589  info->protect = protect;
590  info->ce_mask |= MACSEC_ATTR_PROTECT;
591 
592  return 0;
593 }
594 
595 int rtnl_link_macsec_get_protect(struct rtnl_link *link, uint8_t *protect)
596 {
597  struct macsec_info *info = link->l_info;
598 
599  IS_MACSEC_LINK_ASSERT(link);
600 
601  if (!(info->ce_mask & MACSEC_ATTR_PROTECT))
602  return -NLE_NOATTR;
603 
604  if (protect)
605  *protect = info->protect;
606 
607  return 0;
608 }
609 
610 int rtnl_link_macsec_set_encrypt(struct rtnl_link *link, uint8_t encrypt)
611 {
612  struct macsec_info *info = link->l_info;
613 
614  IS_MACSEC_LINK_ASSERT(link);
615 
616  if (encrypt > 1)
617  return -NLE_INVAL;
618 
619  info->encrypt = encrypt;
620  info->ce_mask |= MACSEC_ATTR_ENCRYPT;
621 
622  return 0;
623 }
624 
625 int rtnl_link_macsec_get_encrypt(struct rtnl_link *link, uint8_t *encrypt)
626 {
627  struct macsec_info *info = link->l_info;
628 
629  IS_MACSEC_LINK_ASSERT(link);
630 
631  if (!(info->ce_mask & MACSEC_ATTR_ENCRYPT))
632  return -NLE_NOATTR;
633 
634  if (encrypt)
635  *encrypt = info->encrypt;
636 
637  return 0;
638 }
639 
640 int rtnl_link_macsec_set_encoding_sa(struct rtnl_link *link, uint8_t encoding_sa)
641 {
642  struct macsec_info *info = link->l_info;
643 
644  IS_MACSEC_LINK_ASSERT(link);
645 
646  if (encoding_sa > 3)
647  return -NLE_INVAL;
648 
649  info->encoding_sa = encoding_sa;
650  info->ce_mask |= MACSEC_ATTR_ENCODING_SA;
651 
652  return 0;
653 }
654 
655 int rtnl_link_macsec_get_encoding_sa(struct rtnl_link *link, uint8_t *encoding_sa)
656 {
657  struct macsec_info *info = link->l_info;
658 
659  IS_MACSEC_LINK_ASSERT(link);
660 
661  if (!(info->ce_mask & MACSEC_ATTR_ENCODING_SA))
662  return -NLE_NOATTR;
663 
664  if (encoding_sa)
665  *encoding_sa = info->encoding_sa;
666 
667  return 0;
668 }
669 
670 int rtnl_link_macsec_set_validation_type(struct rtnl_link *link, enum macsec_validation_type validate)
671 {
672  struct macsec_info *info = link->l_info;
673 
674  IS_MACSEC_LINK_ASSERT(link);
675 
676  if (validate > 1)
677  return -NLE_INVAL;
678 
679  info->validate = validate;
680  info->ce_mask |= MACSEC_ATTR_VALIDATION;
681 
682  return 0;
683 }
684 
685 int rtnl_link_macsec_get_validation_type(struct rtnl_link *link, enum macsec_validation_type *validate)
686 {
687  struct macsec_info *info = link->l_info;
688 
689  IS_MACSEC_LINK_ASSERT(link);
690 
691  if (!(info->ce_mask & MACSEC_ATTR_VALIDATION))
692  return -NLE_NOATTR;
693 
694  if (validate)
695  *validate = info->validate;
696 
697  return 0;
698 }
699 
700 int rtnl_link_macsec_set_replay_protect(struct rtnl_link *link, uint8_t replay_protect)
701 {
702  struct macsec_info *info = link->l_info;
703 
704  IS_MACSEC_LINK_ASSERT(link);
705 
706  if (replay_protect > 1)
707  return -NLE_INVAL;
708 
709  info->replay_protect = replay_protect;
710  info->ce_mask |= MACSEC_ATTR_REPLAY_PROTECT;
711 
712  return 0;
713 }
714 
715 int rtnl_link_macsec_get_replay_protect(struct rtnl_link *link, uint8_t *replay_protect)
716 {
717  struct macsec_info *info = link->l_info;
718 
719  IS_MACSEC_LINK_ASSERT(link);
720 
721  if (!(info->ce_mask & MACSEC_ATTR_REPLAY_PROTECT))
722  return -NLE_NOATTR;
723 
724  if (replay_protect)
725  *replay_protect = info->replay_protect;
726 
727  return 0;
728 }
729 
730 int rtnl_link_macsec_set_window(struct rtnl_link *link, uint32_t window)
731 {
732  struct macsec_info *info = link->l_info;
733 
734  IS_MACSEC_LINK_ASSERT(link);
735 
736  info->window = window;
737  info->ce_mask |= MACSEC_ATTR_WINDOW;
738 
739  return 0;
740 }
741 
742 int rtnl_link_macsec_get_window(struct rtnl_link *link, uint32_t *window)
743 {
744  struct macsec_info *info = link->l_info;
745 
746  IS_MACSEC_LINK_ASSERT(link);
747 
748  if (!(info->ce_mask & MACSEC_ATTR_WINDOW))
749  return -NLE_NOATTR;
750 
751  if (window)
752  *window = info->window;
753 
754  return 0;
755 }
756 
757 int rtnl_link_macsec_set_send_sci(struct rtnl_link *link, uint8_t send_sci)
758 {
759  struct macsec_info *info = link->l_info;
760 
761  IS_MACSEC_LINK_ASSERT(link);
762 
763  if (send_sci > 1)
764  return -NLE_INVAL;
765 
766  info->send_sci = send_sci;
767  info->ce_mask |= MACSEC_ATTR_INC_SCI;
768 
769  return 0;
770 }
771 
772 int rtnl_link_macsec_get_send_sci(struct rtnl_link *link, uint8_t *send_sci)
773 {
774  struct macsec_info *info = link->l_info;
775 
776  IS_MACSEC_LINK_ASSERT(link);
777 
778  if (!(info->ce_mask & MACSEC_ATTR_INC_SCI))
779  return -NLE_NOATTR;
780 
781  if (send_sci)
782  *send_sci = info->send_sci;
783 
784  return 0;
785 }
786 
787 int rtnl_link_macsec_set_end_station(struct rtnl_link *link, uint8_t end_station)
788 {
789  struct macsec_info *info = link->l_info;
790 
791  IS_MACSEC_LINK_ASSERT(link);
792 
793  if (end_station > 1)
794  return -NLE_INVAL;
795 
796  info->end_station = end_station;
797  info->ce_mask |= MACSEC_ATTR_ES;
798 
799  return 0;
800 }
801 
802 int rtnl_link_macsec_get_end_station(struct rtnl_link *link, uint8_t *es)
803 {
804  struct macsec_info *info = link->l_info;
805 
806  IS_MACSEC_LINK_ASSERT(link);
807 
808  if (!(info->ce_mask & MACSEC_ATTR_ES))
809  return -NLE_NOATTR;
810 
811  if (es)
812  *es = info->end_station;
813 
814  return 0;
815 }
816 
817 int rtnl_link_macsec_set_scb(struct rtnl_link *link, uint8_t scb)
818 {
819  struct macsec_info *info = link->l_info;
820 
821  IS_MACSEC_LINK_ASSERT(link);
822 
823  if (scb > 1)
824  return -NLE_INVAL;
825 
826  info->scb = scb;
827  info->ce_mask |= MACSEC_ATTR_SCB;
828 
829  return 0;
830 }
831 
832 int rtnl_link_macsec_get_scb(struct rtnl_link *link, uint8_t *scb)
833 {
834  struct macsec_info *info = link->l_info;
835 
836  IS_MACSEC_LINK_ASSERT(link);
837 
838  if (!(info->ce_mask & MACSEC_ATTR_SCB))
839  return -NLE_NOATTR;
840 
841  if (scb)
842  *scb = info->scb;
843 
844  return 0;
845 }
846 
847 /** @} */
848 
849 /** @} */
Dump object briefly on one line.
Definition: types.h:22
8 bit integer
Definition: attr.h:39
Attribute validation policy.
Definition: attr.h:67
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition: attr.c:599
#define NLA_PUT_U64(msg, attrtype, value)
Add 64 bit integer attribute to netlink message.
Definition: attr.h:251
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition: attr.h:197
int rtnl_link_macsec_get_sci(struct rtnl_link *link, uint64_t *sci)
Get SCI.
Definition: macsec.c:467
Dump all attributes but no statistics.
Definition: types.h:23
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:917
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:992
int rtnl_link_macsec_set_sci(struct rtnl_link *link, uint64_t sci)
Set SCI.
Definition: macsec.c:447
int rtnl_link_macsec_set_port(struct rtnl_link *link, uint16_t port)
Set port identifier.
Definition: macsec.c:489
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:233
int rtnl_link_macsec_get_port(struct rtnl_link *link, uint16_t *port)
Get port identifier.
Definition: macsec.c:508
64 bit integer
Definition: attr.h:42
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:69
32 bit integer
Definition: attr.h:41
Dumping parameters.
Definition: types.h:33
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition: attr.h:215
uint64_t nla_get_u64(const struct nlattr *nla)
Return payload of u64 attribute.
Definition: attr.c:754
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:938
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:895