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