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