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