macsec.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <net/macsec.h>
  3. #include "netdevsim.h"
  4. static int nsim_macsec_find_secy(struct netdevsim *ns, sci_t sci)
  5. {
  6. int i;
  7. for (i = 0; i < NSIM_MACSEC_MAX_SECY_COUNT; i++) {
  8. if (ns->macsec.nsim_secy[i].sci == sci)
  9. return i;
  10. }
  11. return -1;
  12. }
  13. static int nsim_macsec_find_rxsc(struct nsim_secy *ns_secy, sci_t sci)
  14. {
  15. int i;
  16. for (i = 0; i < NSIM_MACSEC_MAX_RXSC_COUNT; i++) {
  17. if (ns_secy->nsim_rxsc[i].sci == sci)
  18. return i;
  19. }
  20. return -1;
  21. }
  22. static int nsim_macsec_add_secy(struct macsec_context *ctx)
  23. {
  24. struct netdevsim *ns = netdev_priv(ctx->netdev);
  25. int idx;
  26. if (ns->macsec.nsim_secy_count == NSIM_MACSEC_MAX_SECY_COUNT)
  27. return -ENOSPC;
  28. for (idx = 0; idx < NSIM_MACSEC_MAX_SECY_COUNT; idx++) {
  29. if (!ns->macsec.nsim_secy[idx].used)
  30. break;
  31. }
  32. if (idx == NSIM_MACSEC_MAX_SECY_COUNT) {
  33. netdev_err(ctx->netdev, "%s: nsim_secy_count not full but all SecYs used\n",
  34. __func__);
  35. return -ENOSPC;
  36. }
  37. netdev_dbg(ctx->netdev, "%s: adding new secy with sci %016llx at index %d\n",
  38. __func__, sci_to_cpu(ctx->secy->sci), idx);
  39. ns->macsec.nsim_secy[idx].used = true;
  40. ns->macsec.nsim_secy[idx].nsim_rxsc_count = 0;
  41. ns->macsec.nsim_secy[idx].sci = ctx->secy->sci;
  42. ns->macsec.nsim_secy_count++;
  43. return 0;
  44. }
  45. static int nsim_macsec_upd_secy(struct macsec_context *ctx)
  46. {
  47. struct netdevsim *ns = netdev_priv(ctx->netdev);
  48. int idx;
  49. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  50. if (idx < 0) {
  51. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  52. __func__, sci_to_cpu(ctx->secy->sci));
  53. return -ENOENT;
  54. }
  55. netdev_dbg(ctx->netdev, "%s: updating secy with sci %016llx at index %d\n",
  56. __func__, sci_to_cpu(ctx->secy->sci), idx);
  57. return 0;
  58. }
  59. static int nsim_macsec_del_secy(struct macsec_context *ctx)
  60. {
  61. struct netdevsim *ns = netdev_priv(ctx->netdev);
  62. int idx;
  63. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  64. if (idx < 0) {
  65. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  66. __func__, sci_to_cpu(ctx->secy->sci));
  67. return -ENOENT;
  68. }
  69. netdev_dbg(ctx->netdev, "%s: removing SecY with SCI %016llx at index %d\n",
  70. __func__, sci_to_cpu(ctx->secy->sci), idx);
  71. ns->macsec.nsim_secy[idx].used = false;
  72. memset(&ns->macsec.nsim_secy[idx], 0, sizeof(ns->macsec.nsim_secy[idx]));
  73. ns->macsec.nsim_secy_count--;
  74. return 0;
  75. }
  76. static int nsim_macsec_add_rxsc(struct macsec_context *ctx)
  77. {
  78. struct netdevsim *ns = netdev_priv(ctx->netdev);
  79. struct nsim_secy *secy;
  80. int idx;
  81. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  82. if (idx < 0) {
  83. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  84. __func__, sci_to_cpu(ctx->secy->sci));
  85. return -ENOENT;
  86. }
  87. secy = &ns->macsec.nsim_secy[idx];
  88. if (secy->nsim_rxsc_count == NSIM_MACSEC_MAX_RXSC_COUNT)
  89. return -ENOSPC;
  90. for (idx = 0; idx < NSIM_MACSEC_MAX_RXSC_COUNT; idx++) {
  91. if (!secy->nsim_rxsc[idx].used)
  92. break;
  93. }
  94. if (idx == NSIM_MACSEC_MAX_RXSC_COUNT)
  95. netdev_err(ctx->netdev, "%s: nsim_rxsc_count not full but all RXSCs used\n",
  96. __func__);
  97. netdev_dbg(ctx->netdev, "%s: adding new rxsc with sci %016llx at index %d\n",
  98. __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
  99. secy->nsim_rxsc[idx].used = true;
  100. secy->nsim_rxsc[idx].sci = ctx->rx_sc->sci;
  101. secy->nsim_rxsc_count++;
  102. return 0;
  103. }
  104. static int nsim_macsec_upd_rxsc(struct macsec_context *ctx)
  105. {
  106. struct netdevsim *ns = netdev_priv(ctx->netdev);
  107. struct nsim_secy *secy;
  108. int idx;
  109. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  110. if (idx < 0) {
  111. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  112. __func__, sci_to_cpu(ctx->secy->sci));
  113. return -ENOENT;
  114. }
  115. secy = &ns->macsec.nsim_secy[idx];
  116. idx = nsim_macsec_find_rxsc(secy, ctx->rx_sc->sci);
  117. if (idx < 0) {
  118. netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
  119. __func__, sci_to_cpu(ctx->rx_sc->sci));
  120. return -ENOENT;
  121. }
  122. netdev_dbg(ctx->netdev, "%s: updating RXSC with sci %016llx at index %d\n",
  123. __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
  124. return 0;
  125. }
  126. static int nsim_macsec_del_rxsc(struct macsec_context *ctx)
  127. {
  128. struct netdevsim *ns = netdev_priv(ctx->netdev);
  129. struct nsim_secy *secy;
  130. int idx;
  131. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  132. if (idx < 0) {
  133. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  134. __func__, sci_to_cpu(ctx->secy->sci));
  135. return -ENOENT;
  136. }
  137. secy = &ns->macsec.nsim_secy[idx];
  138. idx = nsim_macsec_find_rxsc(secy, ctx->rx_sc->sci);
  139. if (idx < 0) {
  140. netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
  141. __func__, sci_to_cpu(ctx->rx_sc->sci));
  142. return -ENOENT;
  143. }
  144. netdev_dbg(ctx->netdev, "%s: removing RXSC with sci %016llx at index %d\n",
  145. __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
  146. secy->nsim_rxsc[idx].used = false;
  147. memset(&secy->nsim_rxsc[idx], 0, sizeof(secy->nsim_rxsc[idx]));
  148. secy->nsim_rxsc_count--;
  149. return 0;
  150. }
  151. static int nsim_macsec_add_rxsa(struct macsec_context *ctx)
  152. {
  153. struct netdevsim *ns = netdev_priv(ctx->netdev);
  154. struct nsim_secy *secy;
  155. int idx;
  156. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  157. if (idx < 0) {
  158. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  159. __func__, sci_to_cpu(ctx->secy->sci));
  160. return -ENOENT;
  161. }
  162. secy = &ns->macsec.nsim_secy[idx];
  163. idx = nsim_macsec_find_rxsc(secy, ctx->sa.rx_sa->sc->sci);
  164. if (idx < 0) {
  165. netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
  166. __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci));
  167. return -ENOENT;
  168. }
  169. netdev_dbg(ctx->netdev, "%s: RXSC with sci %016llx, AN %u\n",
  170. __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
  171. return 0;
  172. }
  173. static int nsim_macsec_upd_rxsa(struct macsec_context *ctx)
  174. {
  175. struct netdevsim *ns = netdev_priv(ctx->netdev);
  176. struct nsim_secy *secy;
  177. int idx;
  178. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  179. if (idx < 0) {
  180. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  181. __func__, sci_to_cpu(ctx->secy->sci));
  182. return -ENOENT;
  183. }
  184. secy = &ns->macsec.nsim_secy[idx];
  185. idx = nsim_macsec_find_rxsc(secy, ctx->sa.rx_sa->sc->sci);
  186. if (idx < 0) {
  187. netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
  188. __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci));
  189. return -ENOENT;
  190. }
  191. netdev_dbg(ctx->netdev, "%s: RXSC with sci %016llx, AN %u\n",
  192. __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
  193. return 0;
  194. }
  195. static int nsim_macsec_del_rxsa(struct macsec_context *ctx)
  196. {
  197. struct netdevsim *ns = netdev_priv(ctx->netdev);
  198. struct nsim_secy *secy;
  199. int idx;
  200. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  201. if (idx < 0) {
  202. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  203. __func__, sci_to_cpu(ctx->secy->sci));
  204. return -ENOENT;
  205. }
  206. secy = &ns->macsec.nsim_secy[idx];
  207. idx = nsim_macsec_find_rxsc(secy, ctx->sa.rx_sa->sc->sci);
  208. if (idx < 0) {
  209. netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
  210. __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci));
  211. return -ENOENT;
  212. }
  213. netdev_dbg(ctx->netdev, "%s: RXSC with sci %016llx, AN %u\n",
  214. __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
  215. return 0;
  216. }
  217. static int nsim_macsec_add_txsa(struct macsec_context *ctx)
  218. {
  219. struct netdevsim *ns = netdev_priv(ctx->netdev);
  220. int idx;
  221. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  222. if (idx < 0) {
  223. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  224. __func__, sci_to_cpu(ctx->secy->sci));
  225. return -ENOENT;
  226. }
  227. netdev_dbg(ctx->netdev, "%s: SECY with sci %016llx, AN %u\n",
  228. __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
  229. return 0;
  230. }
  231. static int nsim_macsec_upd_txsa(struct macsec_context *ctx)
  232. {
  233. struct netdevsim *ns = netdev_priv(ctx->netdev);
  234. int idx;
  235. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  236. if (idx < 0) {
  237. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  238. __func__, sci_to_cpu(ctx->secy->sci));
  239. return -ENOENT;
  240. }
  241. netdev_dbg(ctx->netdev, "%s: SECY with sci %016llx, AN %u\n",
  242. __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
  243. return 0;
  244. }
  245. static int nsim_macsec_del_txsa(struct macsec_context *ctx)
  246. {
  247. struct netdevsim *ns = netdev_priv(ctx->netdev);
  248. int idx;
  249. idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
  250. if (idx < 0) {
  251. netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
  252. __func__, sci_to_cpu(ctx->secy->sci));
  253. return -ENOENT;
  254. }
  255. netdev_dbg(ctx->netdev, "%s: SECY with sci %016llx, AN %u\n",
  256. __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
  257. return 0;
  258. }
  259. static const struct macsec_ops nsim_macsec_ops = {
  260. .mdo_add_secy = nsim_macsec_add_secy,
  261. .mdo_upd_secy = nsim_macsec_upd_secy,
  262. .mdo_del_secy = nsim_macsec_del_secy,
  263. .mdo_add_rxsc = nsim_macsec_add_rxsc,
  264. .mdo_upd_rxsc = nsim_macsec_upd_rxsc,
  265. .mdo_del_rxsc = nsim_macsec_del_rxsc,
  266. .mdo_add_rxsa = nsim_macsec_add_rxsa,
  267. .mdo_upd_rxsa = nsim_macsec_upd_rxsa,
  268. .mdo_del_rxsa = nsim_macsec_del_rxsa,
  269. .mdo_add_txsa = nsim_macsec_add_txsa,
  270. .mdo_upd_txsa = nsim_macsec_upd_txsa,
  271. .mdo_del_txsa = nsim_macsec_del_txsa,
  272. };
  273. void nsim_macsec_init(struct netdevsim *ns)
  274. {
  275. ns->netdev->macsec_ops = &nsim_macsec_ops;
  276. ns->netdev->features |= NETIF_F_HW_MACSEC;
  277. memset(&ns->macsec, 0, sizeof(ns->macsec));
  278. }
  279. void nsim_macsec_teardown(struct netdevsim *ns)
  280. {
  281. }