Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <net/macsec.h>
  4#include "netdevsim.h"
  5
  6static 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
 18static 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
 30static 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 %016llx 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
 59static 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 %016llx 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 %016llx at index %d\n",
 72		   __func__, sci_to_cpu(ctx->secy->sci), idx);
 73
 74	return 0;
 75}
 76
 77static 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 %016llx 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 %016llx 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
 99static 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 %016llx 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 %016llx 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
134static 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 %016llx 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 %016llx 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 %016llx at index %d\n",
156		   __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
157
158	return 0;
159}
160
161static 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 %016llx 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 %016llx 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 %016llx 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
192static 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 %016llx 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 %016llx 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 %016llx, AN %u\n",
214		   __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
215
216	return 0;
217}
218
219static 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 %016llx 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 %016llx 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 %016llx, AN %u\n",
241		   __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
242
243	return 0;
244}
245
246static 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 %016llx 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 %016llx 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 %016llx, AN %u\n",
268		   __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
269
270	return 0;
271}
272
273static 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 %016llx 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 %016llx, AN %u\n",
286		   __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
287
288	return 0;
289}
290
291static 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 %016llx 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 %016llx, AN %u\n",
304		   __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
305
306	return 0;
307}
308
309static 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 %016llx 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 %016llx, AN %u\n",
322		   __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
323
324	return 0;
325}
326
327static 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
342void 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
349void nsim_macsec_teardown(struct netdevsim *ns)
350{
351}