aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-03-13 22:40:24 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-13 22:40:24 -0400
commit010998815230792aa8923a4b72deef0fd0c5f2e5 (patch)
tree0919c709606d0ab3d8dd278f82fd158c559a682e
parentf3c986908cc3b369b57f75de306c635a0074b76b (diff)
parentc09440f7dcb304002dfced8c0fea289eb25f2da0 (diff)
Merge branch 'macsec'
Sabrina Dubroca says: ==================== MACsec IEEE 802.1AE implementation MACsec (IEEE 802.1AE [0]) is a protocol that provides security for wired ethernet LANs. MACsec offers two protection modes: authentication only, or authenticated encryption. MACsec defines "secure channels" that allow transmission from one node to one or more others. Communication on a channel is done over a succession of "secure associations", that each use a specific key. Secure associations are identified by their "association number" in the range 0..3. A secure association is retired when its 32-bit packet number would wrap, and the same association number can later be reused with a new key and packet number. The standard mode of encryption is GCM AES with 128 bits keys, although an extension allows 256 bits keys [1] (not implemented in this submission). When using MACsec, an extra header, called "SecTAG", is added between the ethernet header and the original payload: +---------------------------------+----------------+----------------+ | (MACsec ethertype) | TCI_AN | SL | +---------------------------------+----------------+----------------+ | Packet Number | +-------------------------------------------------------------------+ | Secure Channel Identifier | | (optional) | +-------------------------------------------------------------------+ TCI_AN: version end_station sci_present scb encrypted changed_text association_number (2 bits) SL: short_length (6 bits) unused (2 bits) The ethertype for the packet is set to 0x88E5, and the original ethertype becomes part of the secure payload, which may be encrypted. The ethernet header and the SecTAG are always transmitted in the clear, but are integrity-protected. MACsec supports optional replay protection with a configurable replay window. MACsec is designed to be used with the MKA extension to 802.1X (MACsec Key Agreement protocol) [2], which provides channel attribution and key distribution to the nodes, but can also be used with static keys getting fed manually by an administrator. Optional (not supported yet) features: - confidentiality offset: in encryption mode, part of the payload may be left unencrypted. - choice of cipher suite: GCM AES with 256 bits has been standardised [1]. Implementation A netdevice is created on top of a real device for each TX secure channel, like we do for VLANs. Multiple TX channels can be created on top of the same underlying device. Several other approaches were considered for the RX path: - dev_add_pack: doesn't work, because we want to filter out unprotected packets - transparent mode: MACsec would be enabled directly on the real netdevice. For this, we cannot use a rx_handler directly because MACsec must be available for underlying devices enslaved in a bridge or in a bond, so we need a hook directly in __netif_receive_skb_core. This approach makes it harder to filter non-encrypted packets on RX without forcing the user to setup some rules, so the "transparent" mode is not so transparent after all. It also makes TX more complex than with a dedicated netdevice. One issue with the proposed implementation is that the qdisc layer for the real device operates on already encrypted packets. Netlink API This is currently a mix of rtnetlink (to create the device and set up the TX channel) and genl (for RX channels, secure associations and their keys). genl provides clean demultiplexing of the {TX,RX}{SC,SA} commands. Use cases The normal use case is wired LANs, including veth and slave devices for bonding/teaming or bridges. MACsec can also be used on any device that makes a full ethernet header visible, for example VXLAN. The VXLAN+MACsec setup would be: hypervisor | virtual machine <real_dev>---<VXLAN>---|---<dev>---<macsec_dev> And the packets would look like this: | eth | IP | UDP | VXLAN | eth | MACsec | IP | ... | MACsec ICV | One benefit on this approach to encryption in the cloud is that the payload is encrypted by the tenant, not by the tunnel provider, thus the tenant has full control over the keys. Changes from v1: - rework netlink API after discussion with Johannes Berg - nest attributes, rename - export stats as separate attributes - add some comments - misc small fixes (rcu, constants, struct organization) Changes from RFCv2: - fix ENCODING_SA param validation - add parent link to netlink ifdumps Changes from RFCv1: - addressed comments from Florian and Paolo + kbuild robot - also perform post-decrypt handling after crypto callback - fixed ->dellink behavior Future plans: - offload to hardware, on nics that support it - implement optional features [0] http://standards.ieee.org/getieee802/download/802.1AE-2006.pdf [1] http://standards.ieee.org/getieee802/download/802.1AEbn-2011.pdf [2] http://standards.ieee.org/getieee802/download/802.1X-2010.pdf [3] RFCv1: http://www.spinics.net/lists/netdev/msg358151.html [4] RFCv2: http://www.spinics.net/lists/netdev/msg362389.html [5] v1: http://www.spinics.net/lists/netdev/msg367959.html ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/macsec.c3297
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/if_ether.h1
-rw-r--r--include/uapi/linux/if_link.h29
-rw-r--r--include/uapi/linux/if_macsec.h161
8 files changed, 3505 insertions, 0 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f184fb5bd110..2a1ba62b7da2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -193,6 +193,13 @@ config GENEVE
193 To compile this driver as a module, choose M here: the module 193 To compile this driver as a module, choose M here: the module
194 will be called geneve. 194 will be called geneve.
195 195
196config MACSEC
197 tristate "IEEE 802.1AE MAC-level encryption (MACsec)"
198 select CRYPTO_AES
199 select CRYPTO_GCM
200 ---help---
201 MACsec is an encryption standard for Ethernet.
202
196config NETCONSOLE 203config NETCONSOLE
197 tristate "Network console logging support" 204 tristate "Network console logging support"
198 ---help--- 205 ---help---
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 900b0c5320bb..1aa7cb845663 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_IPVLAN) += ipvlan/
10obj-$(CONFIG_DUMMY) += dummy.o 10obj-$(CONFIG_DUMMY) += dummy.o
11obj-$(CONFIG_EQUALIZER) += eql.o 11obj-$(CONFIG_EQUALIZER) += eql.o
12obj-$(CONFIG_IFB) += ifb.o 12obj-$(CONFIG_IFB) += ifb.o
13obj-$(CONFIG_MACSEC) += macsec.o
13obj-$(CONFIG_MACVLAN) += macvlan.o 14obj-$(CONFIG_MACVLAN) += macvlan.o
14obj-$(CONFIG_MACVTAP) += macvtap.o 15obj-$(CONFIG_MACVTAP) += macvtap.o
15obj-$(CONFIG_MII) += mii.o 16obj-$(CONFIG_MII) += mii.o
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
new file mode 100644
index 000000000000..84d3e5ca8817
--- /dev/null
+++ b/drivers/net/macsec.c
@@ -0,0 +1,3297 @@
1/*
2 * drivers/net/macsec.c - MACsec device
3 *
4 * Copyright (c) 2015 Sabrina Dubroca <sd@queasysnail.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/types.h>
13#include <linux/skbuff.h>
14#include <linux/socket.h>
15#include <linux/module.h>
16#include <crypto/aead.h>
17#include <linux/etherdevice.h>
18#include <linux/rtnetlink.h>
19#include <net/genetlink.h>
20#include <net/sock.h>
21
22#include <uapi/linux/if_macsec.h>
23
24typedef u64 __bitwise sci_t;
25
26#define MACSEC_SCI_LEN 8
27
28/* SecTAG length = macsec_eth_header without the optional SCI */
29#define MACSEC_TAG_LEN 6
30
31struct macsec_eth_header {
32 struct ethhdr eth;
33 /* SecTAG */
34 u8 tci_an;
35#if defined(__LITTLE_ENDIAN_BITFIELD)
36 u8 short_length:6,
37 unused:2;
38#elif defined(__BIG_ENDIAN_BITFIELD)
39 u8 unused:2,
40 short_length:6;
41#else
42#error "Please fix <asm/byteorder.h>"
43#endif
44 __be32 packet_number;
45 u8 secure_channel_id[8]; /* optional */
46} __packed;
47
48#define MACSEC_TCI_VERSION 0x80
49#define MACSEC_TCI_ES 0x40 /* end station */
50#define MACSEC_TCI_SC 0x20 /* SCI present */
51#define MACSEC_TCI_SCB 0x10 /* epon */
52#define MACSEC_TCI_E 0x08 /* encryption */
53#define MACSEC_TCI_C 0x04 /* changed text */
54#define MACSEC_AN_MASK 0x03 /* association number */
55#define MACSEC_TCI_CONFID (MACSEC_TCI_E | MACSEC_TCI_C)
56
57/* minimum secure data length deemed "not short", see IEEE 802.1AE-2006 9.7 */
58#define MIN_NON_SHORT_LEN 48
59
60#define GCM_AES_IV_LEN 12
61#define DEFAULT_ICV_LEN 16
62
63#define MACSEC_NUM_AN 4 /* 2 bits for the association number */
64
65#define for_each_rxsc(secy, sc) \
66 for (sc = rcu_dereference_bh(secy->rx_sc); \
67 sc; \
68 sc = rcu_dereference_bh(sc->next))
69#define for_each_rxsc_rtnl(secy, sc) \
70 for (sc = rtnl_dereference(secy->rx_sc); \
71 sc; \
72 sc = rtnl_dereference(sc->next))
73
74struct gcm_iv {
75 union {
76 u8 secure_channel_id[8];
77 sci_t sci;
78 };
79 __be32 pn;
80};
81
82/**
83 * struct macsec_key - SA key
84 * @id: user-provided key identifier
85 * @tfm: crypto struct, key storage
86 */
87struct macsec_key {
88 u64 id;
89 struct crypto_aead *tfm;
90};
91
92struct macsec_rx_sc_stats {
93 __u64 InOctetsValidated;
94 __u64 InOctetsDecrypted;
95 __u64 InPktsUnchecked;
96 __u64 InPktsDelayed;
97 __u64 InPktsOK;
98 __u64 InPktsInvalid;
99 __u64 InPktsLate;
100 __u64 InPktsNotValid;
101 __u64 InPktsNotUsingSA;
102 __u64 InPktsUnusedSA;
103};
104
105struct macsec_rx_sa_stats {
106 __u32 InPktsOK;
107 __u32 InPktsInvalid;
108 __u32 InPktsNotValid;
109 __u32 InPktsNotUsingSA;
110 __u32 InPktsUnusedSA;
111};
112
113struct macsec_tx_sa_stats {
114 __u32 OutPktsProtected;
115 __u32 OutPktsEncrypted;
116};
117
118struct macsec_tx_sc_stats {
119 __u64 OutPktsProtected;
120 __u64 OutPktsEncrypted;
121 __u64 OutOctetsProtected;
122 __u64 OutOctetsEncrypted;
123};
124
125struct macsec_dev_stats {
126 __u64 OutPktsUntagged;
127 __u64 InPktsUntagged;
128 __u64 OutPktsTooLong;
129 __u64 InPktsNoTag;
130 __u64 InPktsBadTag;
131 __u64 InPktsUnknownSCI;
132 __u64 InPktsNoSCI;
133 __u64 InPktsOverrun;
134};
135
136/**
137 * struct macsec_rx_sa - receive secure association
138 * @active:
139 * @next_pn: packet number expected for the next packet
140 * @lock: protects next_pn manipulations
141 * @key: key structure
142 * @stats: per-SA stats
143 */
144struct macsec_rx_sa {
145 struct macsec_key key;
146 spinlock_t lock;
147 u32 next_pn;
148 atomic_t refcnt;
149 bool active;
150 struct macsec_rx_sa_stats __percpu *stats;
151 struct macsec_rx_sc *sc;
152 struct rcu_head rcu;
153};
154
155struct pcpu_rx_sc_stats {
156 struct macsec_rx_sc_stats stats;
157 struct u64_stats_sync syncp;
158};
159
160/**
161 * struct macsec_rx_sc - receive secure channel
162 * @sci: secure channel identifier for this SC
163 * @active: channel is active
164 * @sa: array of secure associations
165 * @stats: per-SC stats
166 */
167struct macsec_rx_sc {
168 struct macsec_rx_sc __rcu *next;
169 sci_t sci;
170 bool active;
171 struct macsec_rx_sa __rcu *sa[MACSEC_NUM_AN];
172 struct pcpu_rx_sc_stats __percpu *stats;
173 atomic_t refcnt;
174 struct rcu_head rcu_head;
175};
176
177/**
178 * struct macsec_tx_sa - transmit secure association
179 * @active:
180 * @next_pn: packet number to use for the next packet
181 * @lock: protects next_pn manipulations
182 * @key: key structure
183 * @stats: per-SA stats
184 */
185struct macsec_tx_sa {
186 struct macsec_key key;
187 spinlock_t lock;
188 u32 next_pn;
189 atomic_t refcnt;
190 bool active;
191 struct macsec_tx_sa_stats __percpu *stats;
192 struct rcu_head rcu;
193};
194
195struct pcpu_tx_sc_stats {
196 struct macsec_tx_sc_stats stats;
197 struct u64_stats_sync syncp;
198};
199
200/**
201 * struct macsec_tx_sc - transmit secure channel
202 * @active:
203 * @encoding_sa: association number of the SA currently in use
204 * @encrypt: encrypt packets on transmit, or authenticate only
205 * @send_sci: always include the SCI in the SecTAG
206 * @end_station:
207 * @scb: single copy broadcast flag
208 * @sa: array of secure associations
209 * @stats: stats for this TXSC
210 */
211struct macsec_tx_sc {
212 bool active;
213 u8 encoding_sa;
214 bool encrypt;
215 bool send_sci;
216 bool end_station;
217 bool scb;
218 struct macsec_tx_sa __rcu *sa[MACSEC_NUM_AN];
219 struct pcpu_tx_sc_stats __percpu *stats;
220};
221
222#define MACSEC_VALIDATE_DEFAULT MACSEC_VALIDATE_STRICT
223
224/**
225 * struct macsec_secy - MACsec Security Entity
226 * @netdev: netdevice for this SecY
227 * @n_rx_sc: number of receive secure channels configured on this SecY
228 * @sci: secure channel identifier used for tx
229 * @key_len: length of keys used by the cipher suite
230 * @icv_len: length of ICV used by the cipher suite
231 * @validate_frames: validation mode
232 * @operational: MAC_Operational flag
233 * @protect_frames: enable protection for this SecY
234 * @replay_protect: enable packet number checks on receive
235 * @replay_window: size of the replay window
236 * @tx_sc: transmit secure channel
237 * @rx_sc: linked list of receive secure channels
238 */
239struct macsec_secy {
240 struct net_device *netdev;
241 unsigned int n_rx_sc;
242 sci_t sci;
243 u16 key_len;
244 u16 icv_len;
245 enum macsec_validation_type validate_frames;
246 bool operational;
247 bool protect_frames;
248 bool replay_protect;
249 u32 replay_window;
250 struct macsec_tx_sc tx_sc;
251 struct macsec_rx_sc __rcu *rx_sc;
252};
253
254struct pcpu_secy_stats {
255 struct macsec_dev_stats stats;
256 struct u64_stats_sync syncp;
257};
258
259/**
260 * struct macsec_dev - private data
261 * @secy: SecY config
262 * @real_dev: pointer to underlying netdevice
263 * @stats: MACsec device stats
264 * @secys: linked list of SecY's on the underlying device
265 */
266struct macsec_dev {
267 struct macsec_secy secy;
268 struct net_device *real_dev;
269 struct pcpu_secy_stats __percpu *stats;
270 struct list_head secys;
271};
272
273/**
274 * struct macsec_rxh_data - rx_handler private argument
275 * @secys: linked list of SecY's on this underlying device
276 */
277struct macsec_rxh_data {
278 struct list_head secys;
279};
280
281static struct macsec_dev *macsec_priv(const struct net_device *dev)
282{
283 return (struct macsec_dev *)netdev_priv(dev);
284}
285
286static struct macsec_rxh_data *macsec_data_rcu(const struct net_device *dev)
287{
288 return rcu_dereference_bh(dev->rx_handler_data);
289}
290
291static struct macsec_rxh_data *macsec_data_rtnl(const struct net_device *dev)
292{
293 return rtnl_dereference(dev->rx_handler_data);
294}
295
296struct macsec_cb {
297 struct aead_request *req;
298 union {
299 struct macsec_tx_sa *tx_sa;
300 struct macsec_rx_sa *rx_sa;
301 };
302 u8 assoc_num;
303 bool valid;
304 bool has_sci;
305};
306
307static struct macsec_rx_sa *macsec_rxsa_get(struct macsec_rx_sa __rcu *ptr)
308{
309 struct macsec_rx_sa *sa = rcu_dereference_bh(ptr);
310
311 if (!sa || !sa->active)
312 return NULL;
313
314 if (!atomic_inc_not_zero(&sa->refcnt))
315 return NULL;
316
317 return sa;
318}
319
320static void free_rx_sc_rcu(struct rcu_head *head)
321{
322 struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head);
323
324 free_percpu(rx_sc->stats);
325 kfree(rx_sc);
326}
327
328static struct macsec_rx_sc *macsec_rxsc_get(struct macsec_rx_sc *sc)
329{
330 return atomic_inc_not_zero(&sc->refcnt) ? sc : NULL;
331}
332
333static void macsec_rxsc_put(struct macsec_rx_sc *sc)
334{
335 if (atomic_dec_and_test(&sc->refcnt))
336 call_rcu(&sc->rcu_head, free_rx_sc_rcu);
337}
338
339static void free_rxsa(struct rcu_head *head)
340{
341 struct macsec_rx_sa *sa = container_of(head, struct macsec_rx_sa, rcu);
342
343 crypto_free_aead(sa->key.tfm);
344 free_percpu(sa->stats);
345 macsec_rxsc_put(sa->sc);
346 kfree(sa);
347}
348
349static void macsec_rxsa_put(struct macsec_rx_sa *sa)
350{
351 if (atomic_dec_and_test(&sa->refcnt))
352 call_rcu(&sa->rcu, free_rxsa);
353}
354
355static struct macsec_tx_sa *macsec_txsa_get(struct macsec_tx_sa __rcu *ptr)
356{
357 struct macsec_tx_sa *sa = rcu_dereference_bh(ptr);
358
359 if (!sa || !sa->active)
360 return NULL;
361
362 if (!atomic_inc_not_zero(&sa->refcnt))
363 return NULL;
364
365 return sa;
366}
367
368static void free_txsa(struct rcu_head *head)
369{
370 struct macsec_tx_sa *sa = container_of(head, struct macsec_tx_sa, rcu);
371
372 crypto_free_aead(sa->key.tfm);
373 free_percpu(sa->stats);
374 kfree(sa);
375}
376
377static void macsec_txsa_put(struct macsec_tx_sa *sa)
378{
379 if (atomic_dec_and_test(&sa->refcnt))
380 call_rcu(&sa->rcu, free_txsa);
381}
382
383static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb)
384{
385 BUILD_BUG_ON(sizeof(struct macsec_cb) > sizeof(skb->cb));
386 return (struct macsec_cb *)skb->cb;
387}
388
389#define MACSEC_PORT_ES (htons(0x0001))
390#define MACSEC_PORT_SCB (0x0000)
391#define MACSEC_UNDEF_SCI ((__force sci_t)0xffffffffffffffffULL)
392
393#define DEFAULT_SAK_LEN 16
394#define DEFAULT_SEND_SCI true
395#define DEFAULT_ENCRYPT false
396#define DEFAULT_ENCODING_SA 0
397
398static sci_t make_sci(u8 *addr, __be16 port)
399{
400 sci_t sci;
401
402 memcpy(&sci, addr, ETH_ALEN);
403 memcpy(((char *)&sci) + ETH_ALEN, &port, sizeof(port));
404
405 return sci;
406}
407
408static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present)
409{
410 sci_t sci;
411
412 if (sci_present)
413 memcpy(&sci, hdr->secure_channel_id,
414 sizeof(hdr->secure_channel_id));
415 else
416 sci = make_sci(hdr->eth.h_source, MACSEC_PORT_ES);
417
418 return sci;
419}
420
421static unsigned int macsec_sectag_len(bool sci_present)
422{
423 return MACSEC_TAG_LEN + (sci_present ? MACSEC_SCI_LEN : 0);
424}
425
426static unsigned int macsec_hdr_len(bool sci_present)
427{
428 return macsec_sectag_len(sci_present) + ETH_HLEN;
429}
430
431static unsigned int macsec_extra_len(bool sci_present)
432{
433 return macsec_sectag_len(sci_present) + sizeof(__be16);
434}
435
436/* Fill SecTAG according to IEEE 802.1AE-2006 10.5.3 */
437static void macsec_fill_sectag(struct macsec_eth_header *h,
438 const struct macsec_secy *secy, u32 pn)
439{
440 const struct macsec_tx_sc *tx_sc = &secy->tx_sc;
441
442 memset(&h->tci_an, 0, macsec_sectag_len(tx_sc->send_sci));
443 h->eth.h_proto = htons(ETH_P_MACSEC);
444
445 if (tx_sc->send_sci ||
446 (secy->n_rx_sc > 1 && !tx_sc->end_station && !tx_sc->scb)) {
447 h->tci_an |= MACSEC_TCI_SC;
448 memcpy(&h->secure_channel_id, &secy->sci,
449 sizeof(h->secure_channel_id));
450 } else {
451 if (tx_sc->end_station)
452 h->tci_an |= MACSEC_TCI_ES;
453 if (tx_sc->scb)
454 h->tci_an |= MACSEC_TCI_SCB;
455 }
456
457 h->packet_number = htonl(pn);
458
459 /* with GCM, C/E clear for !encrypt, both set for encrypt */
460 if (tx_sc->encrypt)
461 h->tci_an |= MACSEC_TCI_CONFID;
462 else if (secy->icv_len != DEFAULT_ICV_LEN)
463 h->tci_an |= MACSEC_TCI_C;
464
465 h->tci_an |= tx_sc->encoding_sa;
466}
467
468static void macsec_set_shortlen(struct macsec_eth_header *h, size_t data_len)
469{
470 if (data_len < MIN_NON_SHORT_LEN)
471 h->short_length = data_len;
472}
473
474/* validate MACsec packet according to IEEE 802.1AE-2006 9.12 */
475static bool macsec_validate_skb(struct sk_buff *skb, u16 icv_len)
476{
477 struct macsec_eth_header *h = (struct macsec_eth_header *)skb->data;
478 int len = skb->len - 2 * ETH_ALEN;
479 int extra_len = macsec_extra_len(!!(h->tci_an & MACSEC_TCI_SC)) + icv_len;
480
481 /* a) It comprises at least 17 octets */
482 if (skb->len <= 16)
483 return false;
484
485 /* b) MACsec EtherType: already checked */
486
487 /* c) V bit is clear */
488 if (h->tci_an & MACSEC_TCI_VERSION)
489 return false;
490
491 /* d) ES or SCB => !SC */
492 if ((h->tci_an & MACSEC_TCI_ES || h->tci_an & MACSEC_TCI_SCB) &&
493 (h->tci_an & MACSEC_TCI_SC))
494 return false;
495
496 /* e) Bits 7 and 8 of octet 4 of the SecTAG are clear */
497 if (h->unused)
498 return false;
499
500 /* rx.pn != 0 (figure 10-5) */
501 if (!h->packet_number)
502 return false;
503
504 /* length check, f) g) h) i) */
505 if (h->short_length)
506 return len == extra_len + h->short_length;
507 return len >= extra_len + MIN_NON_SHORT_LEN;
508}
509
510#define MACSEC_NEEDED_HEADROOM (macsec_extra_len(true))
511#define MACSEC_NEEDED_TAILROOM MACSEC_MAX_ICV_LEN
512
513static void macsec_fill_iv(unsigned char *iv, sci_t sci, u32 pn)
514{
515 struct gcm_iv *gcm_iv = (struct gcm_iv *)iv;
516
517 gcm_iv->sci = sci;
518 gcm_iv->pn = htonl(pn);
519}
520
521static struct macsec_eth_header *macsec_ethhdr(struct sk_buff *skb)
522{
523 return (struct macsec_eth_header *)skb_mac_header(skb);
524}
525
526static u32 tx_sa_update_pn(struct macsec_tx_sa *tx_sa, struct macsec_secy *secy)
527{
528 u32 pn;
529
530 spin_lock_bh(&tx_sa->lock);
531 pn = tx_sa->next_pn;
532
533 tx_sa->next_pn++;
534 if (tx_sa->next_pn == 0) {
535 pr_debug("PN wrapped, transitioning to !oper\n");
536 tx_sa->active = false;
537 if (secy->protect_frames)
538 secy->operational = false;
539 }
540 spin_unlock_bh(&tx_sa->lock);
541
542 return pn;
543}
544
545static void macsec_encrypt_finish(struct sk_buff *skb, struct net_device *dev)
546{
547 struct macsec_dev *macsec = netdev_priv(dev);
548
549 skb->dev = macsec->real_dev;
550 skb_reset_mac_header(skb);
551 skb->protocol = eth_hdr(skb)->h_proto;
552}
553
554static void macsec_count_tx(struct sk_buff *skb, struct macsec_tx_sc *tx_sc,
555 struct macsec_tx_sa *tx_sa)
556{
557 struct pcpu_tx_sc_stats *txsc_stats = this_cpu_ptr(tx_sc->stats);
558
559 u64_stats_update_begin(&txsc_stats->syncp);
560 if (tx_sc->encrypt) {
561 txsc_stats->stats.OutOctetsEncrypted += skb->len;
562 txsc_stats->stats.OutPktsEncrypted++;
563 this_cpu_inc(tx_sa->stats->OutPktsEncrypted);
564 } else {
565 txsc_stats->stats.OutOctetsProtected += skb->len;
566 txsc_stats->stats.OutPktsProtected++;
567 this_cpu_inc(tx_sa->stats->OutPktsProtected);
568 }
569 u64_stats_update_end(&txsc_stats->syncp);
570}
571
572static void count_tx(struct net_device *dev, int ret, int len)
573{
574 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
575 struct pcpu_sw_netstats *stats = this_cpu_ptr(dev->tstats);
576
577 u64_stats_update_begin(&stats->syncp);
578 stats->tx_packets++;
579 stats->tx_bytes += len;
580 u64_stats_update_end(&stats->syncp);
581 } else {
582 dev->stats.tx_dropped++;
583 }
584}
585
586static void macsec_encrypt_done(struct crypto_async_request *base, int err)
587{
588 struct sk_buff *skb = base->data;
589 struct net_device *dev = skb->dev;
590 struct macsec_dev *macsec = macsec_priv(dev);
591 struct macsec_tx_sa *sa = macsec_skb_cb(skb)->tx_sa;
592 int len, ret;
593
594 aead_request_free(macsec_skb_cb(skb)->req);
595
596 rcu_read_lock_bh();
597 macsec_encrypt_finish(skb, dev);
598 macsec_count_tx(skb, &macsec->secy.tx_sc, macsec_skb_cb(skb)->tx_sa);
599 len = skb->len;
600 ret = dev_queue_xmit(skb);
601 count_tx(dev, ret, len);
602 rcu_read_unlock_bh();
603
604 macsec_txsa_put(sa);
605 dev_put(dev);
606}
607
608static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
609 struct net_device *dev)
610{
611 int ret;
612 struct scatterlist sg[MAX_SKB_FRAGS + 1];
613 unsigned char iv[GCM_AES_IV_LEN];
614 struct ethhdr *eth;
615 struct macsec_eth_header *hh;
616 size_t unprotected_len;
617 struct aead_request *req;
618 struct macsec_secy *secy;
619 struct macsec_tx_sc *tx_sc;
620 struct macsec_tx_sa *tx_sa;
621 struct macsec_dev *macsec = macsec_priv(dev);
622 u32 pn;
623
624 secy = &macsec->secy;
625 tx_sc = &secy->tx_sc;
626
627 /* 10.5.1 TX SA assignment */
628 tx_sa = macsec_txsa_get(tx_sc->sa[tx_sc->encoding_sa]);
629 if (!tx_sa) {
630 secy->operational = false;
631 kfree_skb(skb);
632 return ERR_PTR(-EINVAL);
633 }
634
635 if (unlikely(skb_headroom(skb) < MACSEC_NEEDED_HEADROOM ||
636 skb_tailroom(skb) < MACSEC_NEEDED_TAILROOM)) {
637 struct sk_buff *nskb = skb_copy_expand(skb,
638 MACSEC_NEEDED_HEADROOM,
639 MACSEC_NEEDED_TAILROOM,
640 GFP_ATOMIC);
641 if (likely(nskb)) {
642 consume_skb(skb);
643 skb = nskb;
644 } else {
645 macsec_txsa_put(tx_sa);
646 kfree_skb(skb);
647 return ERR_PTR(-ENOMEM);
648 }
649 } else {
650 skb = skb_unshare(skb, GFP_ATOMIC);
651 if (!skb) {
652 macsec_txsa_put(tx_sa);
653 return ERR_PTR(-ENOMEM);
654 }
655 }
656
657 unprotected_len = skb->len;
658 eth = eth_hdr(skb);
659 hh = (struct macsec_eth_header *)skb_push(skb, macsec_extra_len(tx_sc->send_sci));
660 memmove(hh, eth, 2 * ETH_ALEN);
661
662 pn = tx_sa_update_pn(tx_sa, secy);
663 if (pn == 0) {
664 macsec_txsa_put(tx_sa);
665 kfree_skb(skb);
666 return ERR_PTR(-ENOLINK);
667 }
668 macsec_fill_sectag(hh, secy, pn);
669 macsec_set_shortlen(hh, unprotected_len - 2 * ETH_ALEN);
670
671 macsec_fill_iv(iv, secy->sci, pn);
672
673 skb_put(skb, secy->icv_len);
674
675 if (skb->len - ETH_HLEN > macsec_priv(dev)->real_dev->mtu) {
676 struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats);
677
678 u64_stats_update_begin(&secy_stats->syncp);
679 secy_stats->stats.OutPktsTooLong++;
680 u64_stats_update_end(&secy_stats->syncp);
681
682 macsec_txsa_put(tx_sa);
683 kfree_skb(skb);
684 return ERR_PTR(-EINVAL);
685 }
686
687 req = aead_request_alloc(tx_sa->key.tfm, GFP_ATOMIC);
688 if (!req) {
689 macsec_txsa_put(tx_sa);
690 kfree_skb(skb);
691 return ERR_PTR(-ENOMEM);
692 }
693
694 sg_init_table(sg, MAX_SKB_FRAGS + 1);
695 skb_to_sgvec(skb, sg, 0, skb->len);
696
697 if (tx_sc->encrypt) {
698 int len = skb->len - macsec_hdr_len(tx_sc->send_sci) -
699 secy->icv_len;
700 aead_request_set_crypt(req, sg, sg, len, iv);
701 aead_request_set_ad(req, macsec_hdr_len(tx_sc->send_sci));
702 } else {
703 aead_request_set_crypt(req, sg, sg, 0, iv);
704 aead_request_set_ad(req, skb->len - secy->icv_len);
705 }
706
707 macsec_skb_cb(skb)->req = req;
708 macsec_skb_cb(skb)->tx_sa = tx_sa;
709 aead_request_set_callback(req, 0, macsec_encrypt_done, skb);
710
711 dev_hold(skb->dev);
712 ret = crypto_aead_encrypt(req);
713 if (ret == -EINPROGRESS) {
714 return ERR_PTR(ret);
715 } else if (ret != 0) {
716 dev_put(skb->dev);
717 kfree_skb(skb);
718 aead_request_free(req);
719 macsec_txsa_put(tx_sa);
720 return ERR_PTR(-EINVAL);
721 }
722
723 dev_put(skb->dev);
724 aead_request_free(req);
725 macsec_txsa_put(tx_sa);
726
727 return skb;
728}
729
730static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u32 pn)
731{
732 struct macsec_rx_sa *rx_sa = macsec_skb_cb(skb)->rx_sa;
733 struct pcpu_rx_sc_stats *rxsc_stats = this_cpu_ptr(rx_sa->sc->stats);
734 struct macsec_eth_header *hdr = macsec_ethhdr(skb);
735 u32 lowest_pn = 0;
736
737 spin_lock(&rx_sa->lock);
738 if (rx_sa->next_pn >= secy->replay_window)
739 lowest_pn = rx_sa->next_pn - secy->replay_window;
740
741 /* Now perform replay protection check again
742 * (see IEEE 802.1AE-2006 figure 10-5)
743 */
744 if (secy->replay_protect && pn < lowest_pn) {
745 spin_unlock(&rx_sa->lock);
746 u64_stats_update_begin(&rxsc_stats->syncp);
747 rxsc_stats->stats.InPktsLate++;
748 u64_stats_update_end(&rxsc_stats->syncp);
749 return false;
750 }
751
752 if (secy->validate_frames != MACSEC_VALIDATE_DISABLED) {
753 u64_stats_update_begin(&rxsc_stats->syncp);
754 if (hdr->tci_an & MACSEC_TCI_E)
755 rxsc_stats->stats.InOctetsDecrypted += skb->len;
756 else
757 rxsc_stats->stats.InOctetsValidated += skb->len;
758 u64_stats_update_end(&rxsc_stats->syncp);
759 }
760
761 if (!macsec_skb_cb(skb)->valid) {
762 spin_unlock(&rx_sa->lock);
763
764 /* 10.6.5 */
765 if (hdr->tci_an & MACSEC_TCI_C ||
766 secy->validate_frames == MACSEC_VALIDATE_STRICT) {
767 u64_stats_update_begin(&rxsc_stats->syncp);
768 rxsc_stats->stats.InPktsNotValid++;
769 u64_stats_update_end(&rxsc_stats->syncp);
770 return false;
771 }
772
773 u64_stats_update_begin(&rxsc_stats->syncp);
774 if (secy->validate_frames == MACSEC_VALIDATE_CHECK) {
775 rxsc_stats->stats.InPktsInvalid++;
776 this_cpu_inc(rx_sa->stats->InPktsInvalid);
777 } else if (pn < lowest_pn) {
778 rxsc_stats->stats.InPktsDelayed++;
779 } else {
780 rxsc_stats->stats.InPktsUnchecked++;
781 }
782 u64_stats_update_end(&rxsc_stats->syncp);
783 } else {
784 u64_stats_update_begin(&rxsc_stats->syncp);
785 if (pn < lowest_pn) {
786 rxsc_stats->stats.InPktsDelayed++;
787 } else {
788 rxsc_stats->stats.InPktsOK++;
789 this_cpu_inc(rx_sa->stats->InPktsOK);
790 }
791 u64_stats_update_end(&rxsc_stats->syncp);
792
793 if (pn >= rx_sa->next_pn)
794 rx_sa->next_pn = pn + 1;
795 spin_unlock(&rx_sa->lock);
796 }
797
798 return true;
799}
800
801static void macsec_reset_skb(struct sk_buff *skb, struct net_device *dev)
802{
803 skb->pkt_type = PACKET_HOST;
804 skb->protocol = eth_type_trans(skb, dev);
805
806 skb_reset_network_header(skb);
807 if (!skb_transport_header_was_set(skb))
808 skb_reset_transport_header(skb);
809 skb_reset_mac_len(skb);
810}
811
812static void macsec_finalize_skb(struct sk_buff *skb, u8 icv_len, u8 hdr_len)
813{
814 memmove(skb->data + hdr_len, skb->data, 2 * ETH_ALEN);
815 skb_pull(skb, hdr_len);
816 pskb_trim_unique(skb, skb->len - icv_len);
817}
818
819static void count_rx(struct net_device *dev, int len)
820{
821 struct pcpu_sw_netstats *stats = this_cpu_ptr(dev->tstats);
822
823 u64_stats_update_begin(&stats->syncp);
824 stats->rx_packets++;
825 stats->rx_bytes += len;
826 u64_stats_update_end(&stats->syncp);
827}
828
829static void macsec_decrypt_done(struct crypto_async_request *base, int err)
830{
831 struct sk_buff *skb = base->data;
832 struct net_device *dev = skb->dev;
833 struct macsec_dev *macsec = macsec_priv(dev);
834 struct macsec_rx_sa *rx_sa = macsec_skb_cb(skb)->rx_sa;
835 int len, ret;
836 u32 pn;
837
838 aead_request_free(macsec_skb_cb(skb)->req);
839
840 rcu_read_lock_bh();
841 pn = ntohl(macsec_ethhdr(skb)->packet_number);
842 if (!macsec_post_decrypt(skb, &macsec->secy, pn)) {
843 rcu_read_unlock_bh();
844 kfree_skb(skb);
845 goto out;
846 }
847
848 macsec_finalize_skb(skb, macsec->secy.icv_len,
849 macsec_extra_len(macsec_skb_cb(skb)->has_sci));
850 macsec_reset_skb(skb, macsec->secy.netdev);
851
852 len = skb->len;
853 ret = netif_rx(skb);
854 if (ret == NET_RX_SUCCESS)
855 count_rx(dev, len);
856 else
857 macsec->secy.netdev->stats.rx_dropped++;
858
859 rcu_read_unlock_bh();
860
861out:
862 macsec_rxsa_put(rx_sa);
863 dev_put(dev);
864 return;
865}
866
867static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
868 struct net_device *dev,
869 struct macsec_rx_sa *rx_sa,
870 sci_t sci,
871 struct macsec_secy *secy)
872{
873 int ret;
874 struct scatterlist sg[MAX_SKB_FRAGS + 1];
875 unsigned char iv[GCM_AES_IV_LEN];
876 struct aead_request *req;
877 struct macsec_eth_header *hdr;
878 u16 icv_len = secy->icv_len;
879
880 macsec_skb_cb(skb)->valid = false;
881 skb = skb_share_check(skb, GFP_ATOMIC);
882 if (!skb)
883 return NULL;
884
885 req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC);
886 if (!req) {
887 kfree_skb(skb);
888 return NULL;
889 }
890
891 hdr = (struct macsec_eth_header *)skb->data;
892 macsec_fill_iv(iv, sci, ntohl(hdr->packet_number));
893
894 sg_init_table(sg, MAX_SKB_FRAGS + 1);
895 skb_to_sgvec(skb, sg, 0, skb->len);
896
897 if (hdr->tci_an & MACSEC_TCI_E) {
898 /* confidentiality: ethernet + macsec header
899 * authenticated, encrypted payload
900 */
901 int len = skb->len - macsec_hdr_len(macsec_skb_cb(skb)->has_sci);
902
903 aead_request_set_crypt(req, sg, sg, len, iv);
904 aead_request_set_ad(req, macsec_hdr_len(macsec_skb_cb(skb)->has_sci));
905 skb = skb_unshare(skb, GFP_ATOMIC);
906 if (!skb) {
907 aead_request_free(req);
908 return NULL;
909 }
910 } else {
911 /* integrity only: all headers + data authenticated */
912 aead_request_set_crypt(req, sg, sg, icv_len, iv);
913 aead_request_set_ad(req, skb->len - icv_len);
914 }
915
916 macsec_skb_cb(skb)->req = req;
917 macsec_skb_cb(skb)->rx_sa = rx_sa;
918 skb->dev = dev;
919 aead_request_set_callback(req, 0, macsec_decrypt_done, skb);
920
921 dev_hold(dev);
922 ret = crypto_aead_decrypt(req);
923 if (ret == -EINPROGRESS) {
924 return NULL;
925 } else if (ret != 0) {
926 /* decryption/authentication failed
927 * 10.6 if validateFrames is disabled, deliver anyway
928 */
929 if (ret != -EBADMSG) {
930 kfree_skb(skb);
931 skb = NULL;
932 }
933 } else {
934 macsec_skb_cb(skb)->valid = true;
935 }
936 dev_put(dev);
937
938 aead_request_free(req);
939
940 return skb;
941}
942
943static struct macsec_rx_sc *find_rx_sc(struct macsec_secy *secy, sci_t sci)
944{
945 struct macsec_rx_sc *rx_sc;
946
947 for_each_rxsc(secy, rx_sc) {
948 if (rx_sc->sci == sci)
949 return rx_sc;
950 }
951
952 return NULL;
953}
954
955static struct macsec_rx_sc *find_rx_sc_rtnl(struct macsec_secy *secy, sci_t sci)
956{
957 struct macsec_rx_sc *rx_sc;
958
959 for_each_rxsc_rtnl(secy, rx_sc) {
960 if (rx_sc->sci == sci)
961 return rx_sc;
962 }
963
964 return NULL;
965}
966
967static void handle_not_macsec(struct sk_buff *skb)
968{
969 struct macsec_rxh_data *rxd;
970 struct macsec_dev *macsec;
971
972 rcu_read_lock();
973 rxd = macsec_data_rcu(skb->dev);
974
975 /* 10.6 If the management control validateFrames is not
976 * Strict, frames without a SecTAG are received, counted, and
977 * delivered to the Controlled Port
978 */
979 list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
980 struct sk_buff *nskb;
981 int ret;
982 struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats);
983
984 if (macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
985 u64_stats_update_begin(&secy_stats->syncp);
986 secy_stats->stats.InPktsNoTag++;
987 u64_stats_update_end(&secy_stats->syncp);
988 continue;
989 }
990
991 /* deliver on this port */
992 nskb = skb_clone(skb, GFP_ATOMIC);
993 if (!nskb)
994 break;
995
996 nskb->dev = macsec->secy.netdev;
997
998 ret = netif_rx(nskb);
999 if (ret == NET_RX_SUCCESS) {
1000 u64_stats_update_begin(&secy_stats->syncp);
1001 secy_stats->stats.InPktsUntagged++;
1002 u64_stats_update_end(&secy_stats->syncp);
1003 } else {
1004 macsec->secy.netdev->stats.rx_dropped++;
1005 }
1006 }
1007
1008 rcu_read_unlock();
1009}
1010
1011static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
1012{
1013 struct sk_buff *skb = *pskb;
1014 struct net_device *dev = skb->dev;
1015 struct macsec_eth_header *hdr;
1016 struct macsec_secy *secy = NULL;
1017 struct macsec_rx_sc *rx_sc;
1018 struct macsec_rx_sa *rx_sa;
1019 struct macsec_rxh_data *rxd;
1020 struct macsec_dev *macsec;
1021 sci_t sci;
1022 u32 pn;
1023 bool cbit;
1024 struct pcpu_rx_sc_stats *rxsc_stats;
1025 struct pcpu_secy_stats *secy_stats;
1026 bool pulled_sci;
1027
1028 if (skb_headroom(skb) < ETH_HLEN)
1029 goto drop_direct;
1030
1031 hdr = macsec_ethhdr(skb);
1032 if (hdr->eth.h_proto != htons(ETH_P_MACSEC)) {
1033 handle_not_macsec(skb);
1034
1035 /* and deliver to the uncontrolled port */
1036 return RX_HANDLER_PASS;
1037 }
1038
1039 skb = skb_unshare(skb, GFP_ATOMIC);
1040 if (!skb) {
1041 *pskb = NULL;
1042 return RX_HANDLER_CONSUMED;
1043 }
1044
1045 pulled_sci = pskb_may_pull(skb, macsec_extra_len(true));
1046 if (!pulled_sci) {
1047 if (!pskb_may_pull(skb, macsec_extra_len(false)))
1048 goto drop_direct;
1049 }
1050
1051 hdr = macsec_ethhdr(skb);
1052
1053 /* Frames with a SecTAG that has the TCI E bit set but the C
1054 * bit clear are discarded, as this reserved encoding is used
1055 * to identify frames with a SecTAG that are not to be
1056 * delivered to the Controlled Port.
1057 */
1058 if ((hdr->tci_an & (MACSEC_TCI_C | MACSEC_TCI_E)) == MACSEC_TCI_E)
1059 return RX_HANDLER_PASS;
1060
1061 /* now, pull the extra length */
1062 if (hdr->tci_an & MACSEC_TCI_SC) {
1063 if (!pulled_sci)
1064 goto drop_direct;
1065 }
1066
1067 /* ethernet header is part of crypto processing */
1068 skb_push(skb, ETH_HLEN);
1069
1070 macsec_skb_cb(skb)->has_sci = !!(hdr->tci_an & MACSEC_TCI_SC);
1071 macsec_skb_cb(skb)->assoc_num = hdr->tci_an & MACSEC_AN_MASK;
1072 sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci);
1073
1074 rcu_read_lock();
1075 rxd = macsec_data_rcu(skb->dev);
1076
1077 list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
1078 struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci);
1079
1080 if (sc) {
1081 secy = &macsec->secy;
1082 rx_sc = sc;
1083 break;
1084 }
1085 }
1086
1087 if (!secy)
1088 goto nosci;
1089
1090 dev = secy->netdev;
1091 macsec = macsec_priv(dev);
1092 secy_stats = this_cpu_ptr(macsec->stats);
1093 rxsc_stats = this_cpu_ptr(rx_sc->stats);
1094
1095 if (!macsec_validate_skb(skb, secy->icv_len)) {
1096 u64_stats_update_begin(&secy_stats->syncp);
1097 secy_stats->stats.InPktsBadTag++;
1098 u64_stats_update_end(&secy_stats->syncp);
1099 goto drop_nosa;
1100 }
1101
1102 rx_sa = macsec_rxsa_get(rx_sc->sa[macsec_skb_cb(skb)->assoc_num]);
1103 if (!rx_sa) {
1104 /* 10.6.1 if the SA is not in use */
1105
1106 /* If validateFrames is Strict or the C bit in the
1107 * SecTAG is set, discard
1108 */
1109 if (hdr->tci_an & MACSEC_TCI_C ||
1110 secy->validate_frames == MACSEC_VALIDATE_STRICT) {
1111 u64_stats_update_begin(&rxsc_stats->syncp);
1112 rxsc_stats->stats.InPktsNotUsingSA++;
1113 u64_stats_update_end(&rxsc_stats->syncp);
1114 goto drop_nosa;
1115 }
1116
1117 /* not Strict, the frame (with the SecTAG and ICV
1118 * removed) is delivered to the Controlled Port.
1119 */
1120 u64_stats_update_begin(&rxsc_stats->syncp);
1121 rxsc_stats->stats.InPktsUnusedSA++;
1122 u64_stats_update_end(&rxsc_stats->syncp);
1123 goto deliver;
1124 }
1125
1126 /* First, PN check to avoid decrypting obviously wrong packets */
1127 pn = ntohl(hdr->packet_number);
1128 if (secy->replay_protect) {
1129 bool late;
1130
1131 spin_lock(&rx_sa->lock);
1132 late = rx_sa->next_pn >= secy->replay_window &&
1133 pn < (rx_sa->next_pn - secy->replay_window);
1134 spin_unlock(&rx_sa->lock);
1135
1136 if (late) {
1137 u64_stats_update_begin(&rxsc_stats->syncp);
1138 rxsc_stats->stats.InPktsLate++;
1139 u64_stats_update_end(&rxsc_stats->syncp);
1140 goto drop;
1141 }
1142 }
1143
1144 /* Disabled && !changed text => skip validation */
1145 if (hdr->tci_an & MACSEC_TCI_C ||
1146 secy->validate_frames != MACSEC_VALIDATE_DISABLED)
1147 skb = macsec_decrypt(skb, dev, rx_sa, sci, secy);
1148
1149 if (!skb) {
1150 macsec_rxsa_put(rx_sa);
1151 rcu_read_unlock();
1152 *pskb = NULL;
1153 return RX_HANDLER_CONSUMED;
1154 }
1155
1156 if (!macsec_post_decrypt(skb, secy, pn))
1157 goto drop;
1158
1159deliver:
1160 macsec_finalize_skb(skb, secy->icv_len,
1161 macsec_extra_len(macsec_skb_cb(skb)->has_sci));
1162 macsec_reset_skb(skb, secy->netdev);
1163
1164 macsec_rxsa_put(rx_sa);
1165 count_rx(dev, skb->len);
1166
1167 rcu_read_unlock();
1168
1169 *pskb = skb;
1170 return RX_HANDLER_ANOTHER;
1171
1172drop:
1173 macsec_rxsa_put(rx_sa);
1174drop_nosa:
1175 rcu_read_unlock();
1176drop_direct:
1177 kfree_skb(skb);
1178 *pskb = NULL;
1179 return RX_HANDLER_CONSUMED;
1180
1181nosci:
1182 /* 10.6.1 if the SC is not found */
1183 cbit = !!(hdr->tci_an & MACSEC_TCI_C);
1184 if (!cbit)
1185 macsec_finalize_skb(skb, DEFAULT_ICV_LEN,
1186 macsec_extra_len(macsec_skb_cb(skb)->has_sci));
1187
1188 list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
1189 struct sk_buff *nskb;
1190 int ret;
1191
1192 secy_stats = this_cpu_ptr(macsec->stats);
1193
1194 /* If validateFrames is Strict or the C bit in the
1195 * SecTAG is set, discard
1196 */
1197 if (cbit ||
1198 macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
1199 u64_stats_update_begin(&secy_stats->syncp);
1200 secy_stats->stats.InPktsNoSCI++;
1201 u64_stats_update_end(&secy_stats->syncp);
1202 continue;
1203 }
1204
1205 /* not strict, the frame (with the SecTAG and ICV
1206 * removed) is delivered to the Controlled Port.
1207 */
1208 nskb = skb_clone(skb, GFP_ATOMIC);
1209 if (!nskb)
1210 break;
1211
1212 macsec_reset_skb(nskb, macsec->secy.netdev);
1213
1214 ret = netif_rx(nskb);
1215 if (ret == NET_RX_SUCCESS) {
1216 u64_stats_update_begin(&secy_stats->syncp);
1217 secy_stats->stats.InPktsUnknownSCI++;
1218 u64_stats_update_end(&secy_stats->syncp);
1219 } else {
1220 macsec->secy.netdev->stats.rx_dropped++;
1221 }
1222 }
1223
1224 rcu_read_unlock();
1225 *pskb = skb;
1226 return RX_HANDLER_PASS;
1227}
1228
1229static struct crypto_aead *macsec_alloc_tfm(char *key, int key_len, int icv_len)
1230{
1231 struct crypto_aead *tfm;
1232 int ret;
1233
1234 tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
1235 if (!tfm || IS_ERR(tfm))
1236 return NULL;
1237
1238 ret = crypto_aead_setkey(tfm, key, key_len);
1239 if (ret < 0) {
1240 crypto_free_aead(tfm);
1241 return NULL;
1242 }
1243
1244 ret = crypto_aead_setauthsize(tfm, icv_len);
1245 if (ret < 0) {
1246 crypto_free_aead(tfm);
1247 return NULL;
1248 }
1249
1250 return tfm;
1251}
1252
1253static int init_rx_sa(struct macsec_rx_sa *rx_sa, char *sak, int key_len,
1254 int icv_len)
1255{
1256 rx_sa->stats = alloc_percpu(struct macsec_rx_sa_stats);
1257 if (!rx_sa->stats)
1258 return -1;
1259
1260 rx_sa->key.tfm = macsec_alloc_tfm(sak, key_len, icv_len);
1261 if (!rx_sa->key.tfm) {
1262 free_percpu(rx_sa->stats);
1263 return -1;
1264 }
1265
1266 rx_sa->active = false;
1267 rx_sa->next_pn = 1;
1268 atomic_set(&rx_sa->refcnt, 1);
1269 spin_lock_init(&rx_sa->lock);
1270
1271 return 0;
1272}
1273
1274static void clear_rx_sa(struct macsec_rx_sa *rx_sa)
1275{
1276 rx_sa->active = false;
1277
1278 macsec_rxsa_put(rx_sa);
1279}
1280
1281static void free_rx_sc(struct macsec_rx_sc *rx_sc)
1282{
1283 int i;
1284
1285 for (i = 0; i < MACSEC_NUM_AN; i++) {
1286 struct macsec_rx_sa *sa = rtnl_dereference(rx_sc->sa[i]);
1287
1288 RCU_INIT_POINTER(rx_sc->sa[i], NULL);
1289 if (sa)
1290 clear_rx_sa(sa);
1291 }
1292
1293 macsec_rxsc_put(rx_sc);
1294}
1295
1296static struct macsec_rx_sc *del_rx_sc(struct macsec_secy *secy, sci_t sci)
1297{
1298 struct macsec_rx_sc *rx_sc, __rcu **rx_scp;
1299
1300 for (rx_scp = &secy->rx_sc, rx_sc = rtnl_dereference(*rx_scp);
1301 rx_sc;
1302 rx_scp = &rx_sc->next, rx_sc = rtnl_dereference(*rx_scp)) {
1303 if (rx_sc->sci == sci) {
1304 if (rx_sc->active)
1305 secy->n_rx_sc--;
1306 rcu_assign_pointer(*rx_scp, rx_sc->next);
1307 return rx_sc;
1308 }
1309 }
1310
1311 return NULL;
1312}
1313
1314static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci)
1315{
1316 struct macsec_rx_sc *rx_sc;
1317 struct macsec_dev *macsec;
1318 struct net_device *real_dev = macsec_priv(dev)->real_dev;
1319 struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev);
1320 struct macsec_secy *secy;
1321
1322 list_for_each_entry(macsec, &rxd->secys, secys) {
1323 if (find_rx_sc_rtnl(&macsec->secy, sci))
1324 return ERR_PTR(-EEXIST);
1325 }
1326
1327 rx_sc = kzalloc(sizeof(*rx_sc), GFP_KERNEL);
1328 if (!rx_sc)
1329 return ERR_PTR(-ENOMEM);
1330
1331 rx_sc->stats = netdev_alloc_pcpu_stats(struct pcpu_rx_sc_stats);
1332 if (!rx_sc->stats) {
1333 kfree(rx_sc);
1334 return ERR_PTR(-ENOMEM);
1335 }
1336
1337 rx_sc->sci = sci;
1338 rx_sc->active = true;
1339 atomic_set(&rx_sc->refcnt, 1);
1340
1341 secy = &macsec_priv(dev)->secy;
1342 rcu_assign_pointer(rx_sc->next, secy->rx_sc);
1343 rcu_assign_pointer(secy->rx_sc, rx_sc);
1344
1345 if (rx_sc->active)
1346 secy->n_rx_sc++;
1347
1348 return rx_sc;
1349}
1350
1351static int init_tx_sa(struct macsec_tx_sa *tx_sa, char *sak, int key_len,
1352 int icv_len)
1353{
1354 tx_sa->stats = alloc_percpu(struct macsec_tx_sa_stats);
1355 if (!tx_sa->stats)
1356 return -1;
1357
1358 tx_sa->key.tfm = macsec_alloc_tfm(sak, key_len, icv_len);
1359 if (!tx_sa->key.tfm) {
1360 free_percpu(tx_sa->stats);
1361 return -1;
1362 }
1363
1364 tx_sa->active = false;
1365 atomic_set(&tx_sa->refcnt, 1);
1366 spin_lock_init(&tx_sa->lock);
1367
1368 return 0;
1369}
1370
1371static void clear_tx_sa(struct macsec_tx_sa *tx_sa)
1372{
1373 tx_sa->active = false;
1374
1375 macsec_txsa_put(tx_sa);
1376}
1377
1378static struct genl_family macsec_fam = {
1379 .id = GENL_ID_GENERATE,
1380 .name = MACSEC_GENL_NAME,
1381 .hdrsize = 0,
1382 .version = MACSEC_GENL_VERSION,
1383 .maxattr = MACSEC_ATTR_MAX,
1384 .netnsok = true,
1385};
1386
1387static struct net_device *get_dev_from_nl(struct net *net,
1388 struct nlattr **attrs)
1389{
1390 int ifindex = nla_get_u32(attrs[MACSEC_ATTR_IFINDEX]);
1391 struct net_device *dev;
1392
1393 dev = __dev_get_by_index(net, ifindex);
1394 if (!dev)
1395 return ERR_PTR(-ENODEV);
1396
1397 if (!netif_is_macsec(dev))
1398 return ERR_PTR(-ENODEV);
1399
1400 return dev;
1401}
1402
1403static sci_t nla_get_sci(const struct nlattr *nla)
1404{
1405 return (__force sci_t)nla_get_u64(nla);
1406}
1407
1408static int nla_put_sci(struct sk_buff *skb, int attrtype, sci_t value)
1409{
1410 return nla_put_u64(skb, attrtype, (__force u64)value);
1411}
1412
1413static struct macsec_tx_sa *get_txsa_from_nl(struct net *net,
1414 struct nlattr **attrs,
1415 struct nlattr **tb_sa,
1416 struct net_device **devp,
1417 struct macsec_secy **secyp,
1418 struct macsec_tx_sc **scp,
1419 u8 *assoc_num)
1420{
1421 struct net_device *dev;
1422 struct macsec_secy *secy;
1423 struct macsec_tx_sc *tx_sc;
1424 struct macsec_tx_sa *tx_sa;
1425
1426 if (!tb_sa[MACSEC_SA_ATTR_AN])
1427 return ERR_PTR(-EINVAL);
1428
1429 *assoc_num = nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]);
1430
1431 dev = get_dev_from_nl(net, attrs);
1432 if (IS_ERR(dev))
1433 return ERR_CAST(dev);
1434
1435 if (*assoc_num >= MACSEC_NUM_AN)
1436 return ERR_PTR(-EINVAL);
1437
1438 secy = &macsec_priv(dev)->secy;
1439 tx_sc = &secy->tx_sc;
1440
1441 tx_sa = rtnl_dereference(tx_sc->sa[*assoc_num]);
1442 if (!tx_sa)
1443 return ERR_PTR(-ENODEV);
1444
1445 *devp = dev;
1446 *scp = tx_sc;
1447 *secyp = secy;
1448 return tx_sa;
1449}
1450
1451static struct macsec_rx_sc *get_rxsc_from_nl(struct net *net,
1452 struct nlattr **attrs,
1453 struct nlattr **tb_rxsc,
1454 struct net_device **devp,
1455 struct macsec_secy **secyp)
1456{
1457 struct net_device *dev;
1458 struct macsec_secy *secy;
1459 struct macsec_rx_sc *rx_sc;
1460 sci_t sci;
1461
1462 dev = get_dev_from_nl(net, attrs);
1463 if (IS_ERR(dev))
1464 return ERR_CAST(dev);
1465
1466 secy = &macsec_priv(dev)->secy;
1467
1468 if (!tb_rxsc[MACSEC_RXSC_ATTR_SCI])
1469 return ERR_PTR(-EINVAL);
1470
1471 sci = nla_get_sci(tb_rxsc[MACSEC_RXSC_ATTR_SCI]);
1472 rx_sc = find_rx_sc_rtnl(secy, sci);
1473 if (!rx_sc)
1474 return ERR_PTR(-ENODEV);
1475
1476 *secyp = secy;
1477 *devp = dev;
1478
1479 return rx_sc;
1480}
1481
1482static struct macsec_rx_sa *get_rxsa_from_nl(struct net *net,
1483 struct nlattr **attrs,
1484 struct nlattr **tb_rxsc,
1485 struct nlattr **tb_sa,
1486 struct net_device **devp,
1487 struct macsec_secy **secyp,
1488 struct macsec_rx_sc **scp,
1489 u8 *assoc_num)
1490{
1491 struct macsec_rx_sc *rx_sc;
1492 struct macsec_rx_sa *rx_sa;
1493
1494 if (!tb_sa[MACSEC_SA_ATTR_AN])
1495 return ERR_PTR(-EINVAL);
1496
1497 *assoc_num = nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]);
1498 if (*assoc_num >= MACSEC_NUM_AN)
1499 return ERR_PTR(-EINVAL);
1500
1501 rx_sc = get_rxsc_from_nl(net, attrs, tb_rxsc, devp, secyp);
1502 if (IS_ERR(rx_sc))
1503 return ERR_CAST(rx_sc);
1504
1505 rx_sa = rtnl_dereference(rx_sc->sa[*assoc_num]);
1506 if (!rx_sa)
1507 return ERR_PTR(-ENODEV);
1508
1509 *scp = rx_sc;
1510 return rx_sa;
1511}
1512
1513
1514static const struct nla_policy macsec_genl_policy[NUM_MACSEC_ATTR] = {
1515 [MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 },
1516 [MACSEC_ATTR_RXSC_CONFIG] = { .type = NLA_NESTED },
1517 [MACSEC_ATTR_SA_CONFIG] = { .type = NLA_NESTED },
1518};
1519
1520static const struct nla_policy macsec_genl_rxsc_policy[NUM_MACSEC_RXSC_ATTR] = {
1521 [MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 },
1522 [MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 },
1523};
1524
1525static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = {
1526 [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 },
1527 [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 },
1528 [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 },
1529 [MACSEC_SA_ATTR_KEYID] = { .type = NLA_U64 },
1530 [MACSEC_SA_ATTR_KEY] = { .type = NLA_BINARY,
1531 .len = MACSEC_MAX_KEY_LEN, },
1532};
1533
1534static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa)
1535{
1536 if (!attrs[MACSEC_ATTR_SA_CONFIG])
1537 return -EINVAL;
1538
1539 if (nla_parse_nested(tb_sa, MACSEC_SA_ATTR_MAX, attrs[MACSEC_ATTR_SA_CONFIG],
1540 macsec_genl_sa_policy))
1541 return -EINVAL;
1542
1543 return 0;
1544}
1545
1546static int parse_rxsc_config(struct nlattr **attrs, struct nlattr **tb_rxsc)
1547{
1548 if (!attrs[MACSEC_ATTR_RXSC_CONFIG])
1549 return -EINVAL;
1550
1551 if (nla_parse_nested(tb_rxsc, MACSEC_RXSC_ATTR_MAX, attrs[MACSEC_ATTR_RXSC_CONFIG],
1552 macsec_genl_rxsc_policy))
1553 return -EINVAL;
1554
1555 return 0;
1556}
1557
1558static bool validate_add_rxsa(struct nlattr **attrs)
1559{
1560 if (!attrs[MACSEC_SA_ATTR_AN] ||
1561 !attrs[MACSEC_SA_ATTR_KEY] ||
1562 !attrs[MACSEC_SA_ATTR_KEYID])
1563 return false;
1564
1565 if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN)
1566 return false;
1567
1568 if (attrs[MACSEC_SA_ATTR_PN] && nla_get_u32(attrs[MACSEC_SA_ATTR_PN]) == 0)
1569 return false;
1570
1571 if (attrs[MACSEC_SA_ATTR_ACTIVE]) {
1572 if (nla_get_u8(attrs[MACSEC_SA_ATTR_ACTIVE]) > 1)
1573 return false;
1574 }
1575
1576 return true;
1577}
1578
1579static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
1580{
1581 struct net_device *dev;
1582 struct nlattr **attrs = info->attrs;
1583 struct macsec_secy *secy;
1584 struct macsec_rx_sc *rx_sc;
1585 struct macsec_rx_sa *rx_sa;
1586 unsigned char assoc_num;
1587 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
1588 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
1589
1590 if (!attrs[MACSEC_ATTR_IFINDEX])
1591 return -EINVAL;
1592
1593 if (parse_sa_config(attrs, tb_sa))
1594 return -EINVAL;
1595
1596 if (parse_rxsc_config(attrs, tb_rxsc))
1597 return -EINVAL;
1598
1599 if (!validate_add_rxsa(tb_sa))
1600 return -EINVAL;
1601
1602 rtnl_lock();
1603 rx_sc = get_rxsc_from_nl(genl_info_net(info), attrs, tb_rxsc, &dev, &secy);
1604 if (IS_ERR(rx_sc) || !macsec_rxsc_get(rx_sc)) {
1605 rtnl_unlock();
1606 return PTR_ERR(rx_sc);
1607 }
1608
1609 assoc_num = nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]);
1610
1611 if (nla_len(tb_sa[MACSEC_SA_ATTR_KEY]) != secy->key_len) {
1612 pr_notice("macsec: nl: add_rxsa: bad key length: %d != %d\n",
1613 nla_len(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len);
1614 rtnl_unlock();
1615 return -EINVAL;
1616 }
1617
1618 rx_sa = rtnl_dereference(rx_sc->sa[assoc_num]);
1619 if (rx_sa) {
1620 rtnl_unlock();
1621 return -EBUSY;
1622 }
1623
1624 rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL);
1625 if (init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len,
1626 secy->icv_len)) {
1627 rtnl_unlock();
1628 return -ENOMEM;
1629 }
1630
1631 if (tb_sa[MACSEC_SA_ATTR_PN]) {
1632 spin_lock_bh(&rx_sa->lock);
1633 rx_sa->next_pn = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
1634 spin_unlock_bh(&rx_sa->lock);
1635 }
1636
1637 if (tb_sa[MACSEC_SA_ATTR_ACTIVE])
1638 rx_sa->active = !!nla_get_u8(tb_sa[MACSEC_SA_ATTR_ACTIVE]);
1639
1640 rx_sa->key.id = nla_get_u64(tb_sa[MACSEC_SA_ATTR_KEYID]);
1641 rx_sa->sc = rx_sc;
1642 rcu_assign_pointer(rx_sc->sa[assoc_num], rx_sa);
1643
1644 rtnl_unlock();
1645
1646 return 0;
1647}
1648
1649static bool validate_add_rxsc(struct nlattr **attrs)
1650{
1651 if (!attrs[MACSEC_RXSC_ATTR_SCI])
1652 return false;
1653
1654 if (attrs[MACSEC_RXSC_ATTR_ACTIVE]) {
1655 if (nla_get_u8(attrs[MACSEC_RXSC_ATTR_ACTIVE]) > 1)
1656 return false;
1657 }
1658
1659 return true;
1660}
1661
1662static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
1663{
1664 struct net_device *dev;
1665 sci_t sci = MACSEC_UNDEF_SCI;
1666 struct nlattr **attrs = info->attrs;
1667 struct macsec_rx_sc *rx_sc;
1668 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
1669
1670 if (!attrs[MACSEC_ATTR_IFINDEX])
1671 return -EINVAL;
1672
1673 if (parse_rxsc_config(attrs, tb_rxsc))
1674 return -EINVAL;
1675
1676 if (!validate_add_rxsc(tb_rxsc))
1677 return -EINVAL;
1678
1679 rtnl_lock();
1680 dev = get_dev_from_nl(genl_info_net(info), attrs);
1681 if (IS_ERR(dev)) {
1682 rtnl_unlock();
1683 return PTR_ERR(dev);
1684 }
1685
1686 sci = nla_get_sci(tb_rxsc[MACSEC_RXSC_ATTR_SCI]);
1687
1688 rx_sc = create_rx_sc(dev, sci);
1689 if (IS_ERR(rx_sc)) {
1690 rtnl_unlock();
1691 return PTR_ERR(rx_sc);
1692 }
1693
1694 if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE])
1695 rx_sc->active = !!nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]);
1696
1697 rtnl_unlock();
1698
1699 return 0;
1700}
1701
1702static bool validate_add_txsa(struct nlattr **attrs)
1703{
1704 if (!attrs[MACSEC_SA_ATTR_AN] ||
1705 !attrs[MACSEC_SA_ATTR_PN] ||
1706 !attrs[MACSEC_SA_ATTR_KEY] ||
1707 !attrs[MACSEC_SA_ATTR_KEYID])
1708 return false;
1709
1710 if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN)
1711 return false;
1712
1713 if (nla_get_u32(attrs[MACSEC_SA_ATTR_PN]) == 0)
1714 return false;
1715
1716 if (attrs[MACSEC_SA_ATTR_ACTIVE]) {
1717 if (nla_get_u8(attrs[MACSEC_SA_ATTR_ACTIVE]) > 1)
1718 return false;
1719 }
1720
1721 return true;
1722}
1723
1724static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
1725{
1726 struct net_device *dev;
1727 struct nlattr **attrs = info->attrs;
1728 struct macsec_secy *secy;
1729 struct macsec_tx_sc *tx_sc;
1730 struct macsec_tx_sa *tx_sa;
1731 unsigned char assoc_num;
1732 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
1733
1734 if (!attrs[MACSEC_ATTR_IFINDEX])
1735 return -EINVAL;
1736
1737 if (parse_sa_config(attrs, tb_sa))
1738 return -EINVAL;
1739
1740 if (!validate_add_txsa(tb_sa))
1741 return -EINVAL;
1742
1743 rtnl_lock();
1744 dev = get_dev_from_nl(genl_info_net(info), attrs);
1745 if (IS_ERR(dev)) {
1746 rtnl_unlock();
1747 return PTR_ERR(dev);
1748 }
1749
1750 secy = &macsec_priv(dev)->secy;
1751 tx_sc = &secy->tx_sc;
1752
1753 assoc_num = nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]);
1754
1755 if (nla_len(tb_sa[MACSEC_SA_ATTR_KEY]) != secy->key_len) {
1756 pr_notice("macsec: nl: add_txsa: bad key length: %d != %d\n",
1757 nla_len(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len);
1758 rtnl_unlock();
1759 return -EINVAL;
1760 }
1761
1762 tx_sa = rtnl_dereference(tx_sc->sa[assoc_num]);
1763 if (tx_sa) {
1764 rtnl_unlock();
1765 return -EBUSY;
1766 }
1767
1768 tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL);
1769 if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]),
1770 secy->key_len, secy->icv_len)) {
1771 rtnl_unlock();
1772 return -ENOMEM;
1773 }
1774
1775 tx_sa->key.id = nla_get_u64(tb_sa[MACSEC_SA_ATTR_KEYID]);
1776
1777 spin_lock_bh(&tx_sa->lock);
1778 tx_sa->next_pn = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
1779 spin_unlock_bh(&tx_sa->lock);
1780
1781 if (tb_sa[MACSEC_SA_ATTR_ACTIVE])
1782 tx_sa->active = !!nla_get_u8(tb_sa[MACSEC_SA_ATTR_ACTIVE]);
1783
1784 if (assoc_num == tx_sc->encoding_sa && tx_sa->active)
1785 secy->operational = true;
1786
1787 rcu_assign_pointer(tx_sc->sa[assoc_num], tx_sa);
1788
1789 rtnl_unlock();
1790
1791 return 0;
1792}
1793
1794static int macsec_del_rxsa(struct sk_buff *skb, struct genl_info *info)
1795{
1796 struct nlattr **attrs = info->attrs;
1797 struct net_device *dev;
1798 struct macsec_secy *secy;
1799 struct macsec_rx_sc *rx_sc;
1800 struct macsec_rx_sa *rx_sa;
1801 u8 assoc_num;
1802 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
1803 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
1804
1805 if (!attrs[MACSEC_ATTR_IFINDEX])
1806 return -EINVAL;
1807
1808 if (parse_sa_config(attrs, tb_sa))
1809 return -EINVAL;
1810
1811 if (parse_rxsc_config(attrs, tb_rxsc))
1812 return -EINVAL;
1813
1814 rtnl_lock();
1815 rx_sa = get_rxsa_from_nl(genl_info_net(info), attrs, tb_rxsc, tb_sa,
1816 &dev, &secy, &rx_sc, &assoc_num);
1817 if (IS_ERR(rx_sa)) {
1818 rtnl_unlock();
1819 return PTR_ERR(rx_sa);
1820 }
1821
1822 if (rx_sa->active) {
1823 rtnl_unlock();
1824 return -EBUSY;
1825 }
1826
1827 RCU_INIT_POINTER(rx_sc->sa[assoc_num], NULL);
1828 clear_rx_sa(rx_sa);
1829
1830 rtnl_unlock();
1831
1832 return 0;
1833}
1834
1835static int macsec_del_rxsc(struct sk_buff *skb, struct genl_info *info)
1836{
1837 struct nlattr **attrs = info->attrs;
1838 struct net_device *dev;
1839 struct macsec_secy *secy;
1840 struct macsec_rx_sc *rx_sc;
1841 sci_t sci;
1842 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
1843
1844 if (!attrs[MACSEC_ATTR_IFINDEX])
1845 return -EINVAL;
1846
1847 if (parse_rxsc_config(attrs, tb_rxsc))
1848 return -EINVAL;
1849
1850 if (!tb_rxsc[MACSEC_RXSC_ATTR_SCI])
1851 return -EINVAL;
1852
1853 rtnl_lock();
1854 dev = get_dev_from_nl(genl_info_net(info), info->attrs);
1855 if (IS_ERR(dev)) {
1856 rtnl_unlock();
1857 return PTR_ERR(dev);
1858 }
1859
1860 secy = &macsec_priv(dev)->secy;
1861 sci = nla_get_sci(tb_rxsc[MACSEC_RXSC_ATTR_SCI]);
1862
1863 rx_sc = del_rx_sc(secy, sci);
1864 if (!rx_sc) {
1865 rtnl_unlock();
1866 return -ENODEV;
1867 }
1868
1869 free_rx_sc(rx_sc);
1870 rtnl_unlock();
1871
1872 return 0;
1873}
1874
1875static int macsec_del_txsa(struct sk_buff *skb, struct genl_info *info)
1876{
1877 struct nlattr **attrs = info->attrs;
1878 struct net_device *dev;
1879 struct macsec_secy *secy;
1880 struct macsec_tx_sc *tx_sc;
1881 struct macsec_tx_sa *tx_sa;
1882 u8 assoc_num;
1883 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
1884
1885 if (!attrs[MACSEC_ATTR_IFINDEX])
1886 return -EINVAL;
1887
1888 if (parse_sa_config(attrs, tb_sa))
1889 return -EINVAL;
1890
1891 rtnl_lock();
1892 tx_sa = get_txsa_from_nl(genl_info_net(info), attrs, tb_sa,
1893 &dev, &secy, &tx_sc, &assoc_num);
1894 if (IS_ERR(tx_sa)) {
1895 rtnl_unlock();
1896 return PTR_ERR(tx_sa);
1897 }
1898
1899 if (tx_sa->active) {
1900 rtnl_unlock();
1901 return -EBUSY;
1902 }
1903
1904 RCU_INIT_POINTER(tx_sc->sa[assoc_num], NULL);
1905 clear_tx_sa(tx_sa);
1906
1907 rtnl_unlock();
1908
1909 return 0;
1910}
1911
1912static bool validate_upd_sa(struct nlattr **attrs)
1913{
1914 if (!attrs[MACSEC_SA_ATTR_AN] ||
1915 attrs[MACSEC_SA_ATTR_KEY] ||
1916 attrs[MACSEC_SA_ATTR_KEYID])
1917 return false;
1918
1919 if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN)
1920 return false;
1921
1922 if (attrs[MACSEC_SA_ATTR_PN] && nla_get_u32(attrs[MACSEC_SA_ATTR_PN]) == 0)
1923 return false;
1924
1925 if (attrs[MACSEC_SA_ATTR_ACTIVE]) {
1926 if (nla_get_u8(attrs[MACSEC_SA_ATTR_ACTIVE]) > 1)
1927 return false;
1928 }
1929
1930 return true;
1931}
1932
1933static int macsec_upd_txsa(struct sk_buff *skb, struct genl_info *info)
1934{
1935 struct nlattr **attrs = info->attrs;
1936 struct net_device *dev;
1937 struct macsec_secy *secy;
1938 struct macsec_tx_sc *tx_sc;
1939 struct macsec_tx_sa *tx_sa;
1940 u8 assoc_num;
1941 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
1942
1943 if (!attrs[MACSEC_ATTR_IFINDEX])
1944 return -EINVAL;
1945
1946 if (parse_sa_config(attrs, tb_sa))
1947 return -EINVAL;
1948
1949 if (!validate_upd_sa(tb_sa))
1950 return -EINVAL;
1951
1952 rtnl_lock();
1953 tx_sa = get_txsa_from_nl(genl_info_net(info), attrs, tb_sa,
1954 &dev, &secy, &tx_sc, &assoc_num);
1955 if (IS_ERR(tx_sa)) {
1956 rtnl_unlock();
1957 return PTR_ERR(tx_sa);
1958 }
1959
1960 if (tb_sa[MACSEC_SA_ATTR_PN]) {
1961 spin_lock_bh(&tx_sa->lock);
1962 tx_sa->next_pn = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
1963 spin_unlock_bh(&tx_sa->lock);
1964 }
1965
1966 if (tb_sa[MACSEC_SA_ATTR_ACTIVE])
1967 tx_sa->active = nla_get_u8(tb_sa[MACSEC_SA_ATTR_ACTIVE]);
1968
1969 if (assoc_num == tx_sc->encoding_sa)
1970 secy->operational = tx_sa->active;
1971
1972 rtnl_unlock();
1973
1974 return 0;
1975}
1976
1977static int macsec_upd_rxsa(struct sk_buff *skb, struct genl_info *info)
1978{
1979 struct nlattr **attrs = info->attrs;
1980 struct net_device *dev;
1981 struct macsec_secy *secy;
1982 struct macsec_rx_sc *rx_sc;
1983 struct macsec_rx_sa *rx_sa;
1984 u8 assoc_num;
1985 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
1986 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
1987
1988 if (!attrs[MACSEC_ATTR_IFINDEX])
1989 return -EINVAL;
1990
1991 if (parse_rxsc_config(attrs, tb_rxsc))
1992 return -EINVAL;
1993
1994 if (parse_sa_config(attrs, tb_sa))
1995 return -EINVAL;
1996
1997 if (!validate_upd_sa(tb_sa))
1998 return -EINVAL;
1999
2000 rtnl_lock();
2001 rx_sa = get_rxsa_from_nl(genl_info_net(info), attrs, tb_rxsc, tb_sa,
2002 &dev, &secy, &rx_sc, &assoc_num);
2003 if (IS_ERR(rx_sa)) {
2004 rtnl_unlock();
2005 return PTR_ERR(rx_sa);
2006 }
2007
2008 if (tb_sa[MACSEC_SA_ATTR_PN]) {
2009 spin_lock_bh(&rx_sa->lock);
2010 rx_sa->next_pn = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
2011 spin_unlock_bh(&rx_sa->lock);
2012 }
2013
2014 if (tb_sa[MACSEC_SA_ATTR_ACTIVE])
2015 rx_sa->active = nla_get_u8(tb_sa[MACSEC_SA_ATTR_ACTIVE]);
2016
2017 rtnl_unlock();
2018 return 0;
2019}
2020
2021static int macsec_upd_rxsc(struct sk_buff *skb, struct genl_info *info)
2022{
2023 struct nlattr **attrs = info->attrs;
2024 struct net_device *dev;
2025 struct macsec_secy *secy;
2026 struct macsec_rx_sc *rx_sc;
2027 struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
2028
2029 if (!attrs[MACSEC_ATTR_IFINDEX])
2030 return -EINVAL;
2031
2032 if (parse_rxsc_config(attrs, tb_rxsc))
2033 return -EINVAL;
2034
2035 if (!validate_add_rxsc(tb_rxsc))
2036 return -EINVAL;
2037
2038 rtnl_lock();
2039 rx_sc = get_rxsc_from_nl(genl_info_net(info), attrs, tb_rxsc, &dev, &secy);
2040 if (IS_ERR(rx_sc)) {
2041 rtnl_unlock();
2042 return PTR_ERR(rx_sc);
2043 }
2044
2045 if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]) {
2046 bool new = !!nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]);
2047
2048 if (rx_sc->active != new)
2049 secy->n_rx_sc += new ? 1 : -1;
2050
2051 rx_sc->active = new;
2052 }
2053
2054 rtnl_unlock();
2055
2056 return 0;
2057}
2058
2059static int copy_tx_sa_stats(struct sk_buff *skb,
2060 struct macsec_tx_sa_stats __percpu *pstats)
2061{
2062 struct macsec_tx_sa_stats sum = {0, };
2063 int cpu;
2064
2065 for_each_possible_cpu(cpu) {
2066 const struct macsec_tx_sa_stats *stats = per_cpu_ptr(pstats, cpu);
2067
2068 sum.OutPktsProtected += stats->OutPktsProtected;
2069 sum.OutPktsEncrypted += stats->OutPktsEncrypted;
2070 }
2071
2072 if (nla_put_u32(skb, MACSEC_SA_STATS_ATTR_OUT_PKTS_PROTECTED, sum.OutPktsProtected) ||
2073 nla_put_u32(skb, MACSEC_SA_STATS_ATTR_OUT_PKTS_ENCRYPTED, sum.OutPktsEncrypted))
2074 return -EMSGSIZE;
2075
2076 return 0;
2077}
2078
2079static int copy_rx_sa_stats(struct sk_buff *skb,
2080 struct macsec_rx_sa_stats __percpu *pstats)
2081{
2082 struct macsec_rx_sa_stats sum = {0, };
2083 int cpu;
2084
2085 for_each_possible_cpu(cpu) {
2086 const struct macsec_rx_sa_stats *stats = per_cpu_ptr(pstats, cpu);
2087
2088 sum.InPktsOK += stats->InPktsOK;
2089 sum.InPktsInvalid += stats->InPktsInvalid;
2090 sum.InPktsNotValid += stats->InPktsNotValid;
2091 sum.InPktsNotUsingSA += stats->InPktsNotUsingSA;
2092 sum.InPktsUnusedSA += stats->InPktsUnusedSA;
2093 }
2094
2095 if (nla_put_u32(skb, MACSEC_SA_STATS_ATTR_IN_PKTS_OK, sum.InPktsOK) ||
2096 nla_put_u32(skb, MACSEC_SA_STATS_ATTR_IN_PKTS_INVALID, sum.InPktsInvalid) ||
2097 nla_put_u32(skb, MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_VALID, sum.InPktsNotValid) ||
2098 nla_put_u32(skb, MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_USING_SA, sum.InPktsNotUsingSA) ||
2099 nla_put_u32(skb, MACSEC_SA_STATS_ATTR_IN_PKTS_UNUSED_SA, sum.InPktsUnusedSA))
2100 return -EMSGSIZE;
2101
2102 return 0;
2103}
2104
2105static int copy_rx_sc_stats(struct sk_buff *skb,
2106 struct pcpu_rx_sc_stats __percpu *pstats)
2107{
2108 struct macsec_rx_sc_stats sum = {0, };
2109 int cpu;
2110
2111 for_each_possible_cpu(cpu) {
2112 const struct pcpu_rx_sc_stats *stats;
2113 struct macsec_rx_sc_stats tmp;
2114 unsigned int start;
2115
2116 stats = per_cpu_ptr(pstats, cpu);
2117 do {
2118 start = u64_stats_fetch_begin_irq(&stats->syncp);
2119 memcpy(&tmp, &stats->stats, sizeof(tmp));
2120 } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
2121
2122 sum.InOctetsValidated += tmp.InOctetsValidated;
2123 sum.InOctetsDecrypted += tmp.InOctetsDecrypted;
2124 sum.InPktsUnchecked += tmp.InPktsUnchecked;
2125 sum.InPktsDelayed += tmp.InPktsDelayed;
2126 sum.InPktsOK += tmp.InPktsOK;
2127 sum.InPktsInvalid += tmp.InPktsInvalid;
2128 sum.InPktsLate += tmp.InPktsLate;
2129 sum.InPktsNotValid += tmp.InPktsNotValid;
2130 sum.InPktsNotUsingSA += tmp.InPktsNotUsingSA;
2131 sum.InPktsUnusedSA += tmp.InPktsUnusedSA;
2132 }
2133
2134 if (nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_OCTETS_VALIDATED, sum.InOctetsValidated) ||
2135 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_OCTETS_DECRYPTED, sum.InOctetsDecrypted) ||
2136 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNCHECKED, sum.InPktsUnchecked) ||
2137 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_DELAYED, sum.InPktsDelayed) ||
2138 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_OK, sum.InPktsOK) ||
2139 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_INVALID, sum.InPktsInvalid) ||
2140 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_LATE, sum.InPktsLate) ||
2141 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_VALID, sum.InPktsNotValid) ||
2142 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_USING_SA, sum.InPktsNotUsingSA) ||
2143 nla_put_u64(skb, MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNUSED_SA, sum.InPktsUnusedSA))
2144 return -EMSGSIZE;
2145
2146 return 0;
2147}
2148
2149static int copy_tx_sc_stats(struct sk_buff *skb,
2150 struct pcpu_tx_sc_stats __percpu *pstats)
2151{
2152 struct macsec_tx_sc_stats sum = {0, };
2153 int cpu;
2154
2155 for_each_possible_cpu(cpu) {
2156 const struct pcpu_tx_sc_stats *stats;
2157 struct macsec_tx_sc_stats tmp;
2158 unsigned int start;
2159
2160 stats = per_cpu_ptr(pstats, cpu);
2161 do {
2162 start = u64_stats_fetch_begin_irq(&stats->syncp);
2163 memcpy(&tmp, &stats->stats, sizeof(tmp));
2164 } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
2165
2166 sum.OutPktsProtected += tmp.OutPktsProtected;
2167 sum.OutPktsEncrypted += tmp.OutPktsEncrypted;
2168 sum.OutOctetsProtected += tmp.OutOctetsProtected;
2169 sum.OutOctetsEncrypted += tmp.OutOctetsEncrypted;
2170 }
2171
2172 if (nla_put_u64(skb, MACSEC_TXSC_STATS_ATTR_OUT_PKTS_PROTECTED, sum.OutPktsProtected) ||
2173 nla_put_u64(skb, MACSEC_TXSC_STATS_ATTR_OUT_PKTS_ENCRYPTED, sum.OutPktsEncrypted) ||
2174 nla_put_u64(skb, MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_PROTECTED, sum.OutOctetsProtected) ||
2175 nla_put_u64(skb, MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_ENCRYPTED, sum.OutOctetsEncrypted))
2176 return -EMSGSIZE;
2177
2178 return 0;
2179}
2180
2181static int copy_secy_stats(struct sk_buff *skb,
2182 struct pcpu_secy_stats __percpu *pstats)
2183{
2184 struct macsec_dev_stats sum = {0, };
2185 int cpu;
2186
2187 for_each_possible_cpu(cpu) {
2188 const struct pcpu_secy_stats *stats;
2189 struct macsec_dev_stats tmp;
2190 unsigned int start;
2191
2192 stats = per_cpu_ptr(pstats, cpu);
2193 do {
2194 start = u64_stats_fetch_begin_irq(&stats->syncp);
2195 memcpy(&tmp, &stats->stats, sizeof(tmp));
2196 } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
2197
2198 sum.OutPktsUntagged += tmp.OutPktsUntagged;
2199 sum.InPktsUntagged += tmp.InPktsUntagged;
2200 sum.OutPktsTooLong += tmp.OutPktsTooLong;
2201 sum.InPktsNoTag += tmp.InPktsNoTag;
2202 sum.InPktsBadTag += tmp.InPktsBadTag;
2203 sum.InPktsUnknownSCI += tmp.InPktsUnknownSCI;
2204 sum.InPktsNoSCI += tmp.InPktsNoSCI;
2205 sum.InPktsOverrun += tmp.InPktsOverrun;
2206 }
2207
2208 if (nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_OUT_PKTS_UNTAGGED, sum.OutPktsUntagged) ||
2209 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_IN_PKTS_UNTAGGED, sum.InPktsUntagged) ||
2210 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_OUT_PKTS_TOO_LONG, sum.OutPktsTooLong) ||
2211 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_TAG, sum.InPktsNoTag) ||
2212 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_IN_PKTS_BAD_TAG, sum.InPktsBadTag) ||
2213 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_IN_PKTS_UNKNOWN_SCI, sum.InPktsUnknownSCI) ||
2214 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_SCI, sum.InPktsNoSCI) ||
2215 nla_put_u64(skb, MACSEC_SECY_STATS_ATTR_IN_PKTS_OVERRUN, sum.InPktsOverrun))
2216 return -EMSGSIZE;
2217
2218 return 0;
2219}
2220
2221static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb)
2222{
2223 struct macsec_tx_sc *tx_sc = &secy->tx_sc;
2224 struct nlattr *secy_nest = nla_nest_start(skb, MACSEC_ATTR_SECY);
2225
2226 if (!secy_nest)
2227 return 1;
2228
2229 if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) ||
2230 nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, DEFAULT_CIPHER_ID) ||
2231 nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) ||
2232 nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) ||
2233 nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) ||
2234 nla_put_u8(skb, MACSEC_SECY_ATTR_REPLAY, secy->replay_protect) ||
2235 nla_put_u8(skb, MACSEC_SECY_ATTR_VALIDATE, secy->validate_frames) ||
2236 nla_put_u8(skb, MACSEC_SECY_ATTR_ENCRYPT, tx_sc->encrypt) ||
2237 nla_put_u8(skb, MACSEC_SECY_ATTR_INC_SCI, tx_sc->send_sci) ||
2238 nla_put_u8(skb, MACSEC_SECY_ATTR_ES, tx_sc->end_station) ||
2239 nla_put_u8(skb, MACSEC_SECY_ATTR_SCB, tx_sc->scb) ||
2240 nla_put_u8(skb, MACSEC_SECY_ATTR_ENCODING_SA, tx_sc->encoding_sa))
2241 goto cancel;
2242
2243 if (secy->replay_protect) {
2244 if (nla_put_u32(skb, MACSEC_SECY_ATTR_WINDOW, secy->replay_window))
2245 goto cancel;
2246 }
2247
2248 nla_nest_end(skb, secy_nest);
2249 return 0;
2250
2251cancel:
2252 nla_nest_cancel(skb, secy_nest);
2253 return 1;
2254}
2255
2256static int dump_secy(struct macsec_secy *secy, struct net_device *dev,
2257 struct sk_buff *skb, struct netlink_callback *cb)
2258{
2259 struct macsec_rx_sc *rx_sc;
2260 struct macsec_tx_sc *tx_sc = &secy->tx_sc;
2261 struct nlattr *txsa_list, *rxsc_list;
2262 int i, j;
2263 void *hdr;
2264 struct nlattr *attr;
2265
2266 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
2267 &macsec_fam, NLM_F_MULTI, MACSEC_CMD_GET_TXSC);
2268 if (!hdr)
2269 return -EMSGSIZE;
2270
2271 rtnl_lock();
2272
2273 if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex))
2274 goto nla_put_failure;
2275
2276 if (nla_put_secy(secy, skb))
2277 goto nla_put_failure;
2278
2279 attr = nla_nest_start(skb, MACSEC_ATTR_TXSC_STATS);
2280 if (!attr)
2281 goto nla_put_failure;
2282 if (copy_tx_sc_stats(skb, tx_sc->stats)) {
2283 nla_nest_cancel(skb, attr);
2284 goto nla_put_failure;
2285 }
2286 nla_nest_end(skb, attr);
2287
2288 attr = nla_nest_start(skb, MACSEC_ATTR_SECY_STATS);
2289 if (!attr)
2290 goto nla_put_failure;
2291 if (copy_secy_stats(skb, macsec_priv(dev)->stats)) {
2292 nla_nest_cancel(skb, attr);
2293 goto nla_put_failure;
2294 }
2295 nla_nest_end(skb, attr);
2296
2297 txsa_list = nla_nest_start(skb, MACSEC_ATTR_TXSA_LIST);
2298 if (!txsa_list)
2299 goto nla_put_failure;
2300 for (i = 0, j = 1; i < MACSEC_NUM_AN; i++) {
2301 struct macsec_tx_sa *tx_sa = rtnl_dereference(tx_sc->sa[i]);
2302 struct nlattr *txsa_nest;
2303
2304 if (!tx_sa)
2305 continue;
2306
2307 txsa_nest = nla_nest_start(skb, j++);
2308 if (!txsa_nest) {
2309 nla_nest_cancel(skb, txsa_list);
2310 goto nla_put_failure;
2311 }
2312
2313 if (nla_put_u8(skb, MACSEC_SA_ATTR_AN, i) ||
2314 nla_put_u32(skb, MACSEC_SA_ATTR_PN, tx_sa->next_pn) ||
2315 nla_put_u64(skb, MACSEC_SA_ATTR_KEYID, tx_sa->key.id) ||
2316 nla_put_u8(skb, MACSEC_SA_ATTR_ACTIVE, tx_sa->active)) {
2317 nla_nest_cancel(skb, txsa_nest);
2318 nla_nest_cancel(skb, txsa_list);
2319 goto nla_put_failure;
2320 }
2321
2322 attr = nla_nest_start(skb, MACSEC_SA_ATTR_STATS);
2323 if (!attr) {
2324 nla_nest_cancel(skb, txsa_nest);
2325 nla_nest_cancel(skb, txsa_list);
2326 goto nla_put_failure;
2327 }
2328 if (copy_tx_sa_stats(skb, tx_sa->stats)) {
2329 nla_nest_cancel(skb, attr);
2330 nla_nest_cancel(skb, txsa_nest);
2331 nla_nest_cancel(skb, txsa_list);
2332 goto nla_put_failure;
2333 }
2334 nla_nest_end(skb, attr);
2335
2336 nla_nest_end(skb, txsa_nest);
2337 }
2338 nla_nest_end(skb, txsa_list);
2339
2340 rxsc_list = nla_nest_start(skb, MACSEC_ATTR_RXSC_LIST);
2341 if (!rxsc_list)
2342 goto nla_put_failure;
2343
2344 j = 1;
2345 for_each_rxsc_rtnl(secy, rx_sc) {
2346 int k;
2347 struct nlattr *rxsa_list;
2348 struct nlattr *rxsc_nest = nla_nest_start(skb, j++);
2349
2350 if (!rxsc_nest) {
2351 nla_nest_cancel(skb, rxsc_list);
2352 goto nla_put_failure;
2353 }
2354
2355 if (nla_put_u8(skb, MACSEC_RXSC_ATTR_ACTIVE, rx_sc->active) ||
2356 nla_put_sci(skb, MACSEC_RXSC_ATTR_SCI, rx_sc->sci)) {
2357 nla_nest_cancel(skb, rxsc_nest);
2358 nla_nest_cancel(skb, rxsc_list);
2359 goto nla_put_failure;
2360 }
2361
2362 attr = nla_nest_start(skb, MACSEC_RXSC_ATTR_STATS);
2363 if (!attr) {
2364 nla_nest_cancel(skb, rxsc_nest);
2365 nla_nest_cancel(skb, rxsc_list);
2366 goto nla_put_failure;
2367 }
2368 if (copy_rx_sc_stats(skb, rx_sc->stats)) {
2369 nla_nest_cancel(skb, attr);
2370 nla_nest_cancel(skb, rxsc_nest);
2371 nla_nest_cancel(skb, rxsc_list);
2372 goto nla_put_failure;
2373 }
2374 nla_nest_end(skb, attr);
2375
2376 rxsa_list = nla_nest_start(skb, MACSEC_RXSC_ATTR_SA_LIST);
2377 if (!rxsa_list) {
2378 nla_nest_cancel(skb, rxsc_nest);
2379 nla_nest_cancel(skb, rxsc_list);
2380 goto nla_put_failure;
2381 }
2382
2383 for (i = 0, k = 1; i < MACSEC_NUM_AN; i++) {
2384 struct macsec_rx_sa *rx_sa = rtnl_dereference(rx_sc->sa[i]);
2385 struct nlattr *rxsa_nest;
2386
2387 if (!rx_sa)
2388 continue;
2389
2390 rxsa_nest = nla_nest_start(skb, k++);
2391 if (!rxsa_nest) {
2392 nla_nest_cancel(skb, rxsa_list);
2393 nla_nest_cancel(skb, rxsc_nest);
2394 nla_nest_cancel(skb, rxsc_list);
2395 goto nla_put_failure;
2396 }
2397
2398 attr = nla_nest_start(skb, MACSEC_SA_ATTR_STATS);
2399 if (!attr) {
2400 nla_nest_cancel(skb, rxsa_list);
2401 nla_nest_cancel(skb, rxsc_nest);
2402 nla_nest_cancel(skb, rxsc_list);
2403 goto nla_put_failure;
2404 }
2405 if (copy_rx_sa_stats(skb, rx_sa->stats)) {
2406 nla_nest_cancel(skb, attr);
2407 nla_nest_cancel(skb, rxsa_list);
2408 nla_nest_cancel(skb, rxsc_nest);
2409 nla_nest_cancel(skb, rxsc_list);
2410 goto nla_put_failure;
2411 }
2412 nla_nest_end(skb, attr);
2413
2414 if (nla_put_u8(skb, MACSEC_SA_ATTR_AN, i) ||
2415 nla_put_u32(skb, MACSEC_SA_ATTR_PN, rx_sa->next_pn) ||
2416 nla_put_u64(skb, MACSEC_SA_ATTR_KEYID, rx_sa->key.id) ||
2417 nla_put_u8(skb, MACSEC_SA_ATTR_ACTIVE, rx_sa->active)) {
2418 nla_nest_cancel(skb, rxsa_nest);
2419 nla_nest_cancel(skb, rxsc_nest);
2420 nla_nest_cancel(skb, rxsc_list);
2421 goto nla_put_failure;
2422 }
2423 nla_nest_end(skb, rxsa_nest);
2424 }
2425
2426 nla_nest_end(skb, rxsa_list);
2427 nla_nest_end(skb, rxsc_nest);
2428 }
2429
2430 nla_nest_end(skb, rxsc_list);
2431
2432 rtnl_unlock();
2433
2434 genlmsg_end(skb, hdr);
2435
2436 return 0;
2437
2438nla_put_failure:
2439 rtnl_unlock();
2440 genlmsg_cancel(skb, hdr);
2441 return -EMSGSIZE;
2442}
2443
2444static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb)
2445{
2446 struct net *net = sock_net(skb->sk);
2447 struct net_device *dev;
2448 int dev_idx, d;
2449
2450 dev_idx = cb->args[0];
2451
2452 d = 0;
2453 for_each_netdev(net, dev) {
2454 struct macsec_secy *secy;
2455
2456 if (d < dev_idx)
2457 goto next;
2458
2459 if (!netif_is_macsec(dev))
2460 goto next;
2461
2462 secy = &macsec_priv(dev)->secy;
2463 if (dump_secy(secy, dev, skb, cb) < 0)
2464 goto done;
2465next:
2466 d++;
2467 }
2468
2469done:
2470 cb->args[0] = d;
2471 return skb->len;
2472}
2473
2474static const struct genl_ops macsec_genl_ops[] = {
2475 {
2476 .cmd = MACSEC_CMD_GET_TXSC,
2477 .dumpit = macsec_dump_txsc,
2478 .policy = macsec_genl_policy,
2479 },
2480 {
2481 .cmd = MACSEC_CMD_ADD_RXSC,
2482 .doit = macsec_add_rxsc,
2483 .policy = macsec_genl_policy,
2484 .flags = GENL_ADMIN_PERM,
2485 },
2486 {
2487 .cmd = MACSEC_CMD_DEL_RXSC,
2488 .doit = macsec_del_rxsc,
2489 .policy = macsec_genl_policy,
2490 .flags = GENL_ADMIN_PERM,
2491 },
2492 {
2493 .cmd = MACSEC_CMD_UPD_RXSC,
2494 .doit = macsec_upd_rxsc,
2495 .policy = macsec_genl_policy,
2496 .flags = GENL_ADMIN_PERM,
2497 },
2498 {
2499 .cmd = MACSEC_CMD_ADD_TXSA,
2500 .doit = macsec_add_txsa,
2501 .policy = macsec_genl_policy,
2502 .flags = GENL_ADMIN_PERM,
2503 },
2504 {
2505 .cmd = MACSEC_CMD_DEL_TXSA,
2506 .doit = macsec_del_txsa,
2507 .policy = macsec_genl_policy,
2508 .flags = GENL_ADMIN_PERM,
2509 },
2510 {
2511 .cmd = MACSEC_CMD_UPD_TXSA,
2512 .doit = macsec_upd_txsa,
2513 .policy = macsec_genl_policy,
2514 .flags = GENL_ADMIN_PERM,
2515 },
2516 {
2517 .cmd = MACSEC_CMD_ADD_RXSA,
2518 .doit = macsec_add_rxsa,
2519 .policy = macsec_genl_policy,
2520 .flags = GENL_ADMIN_PERM,
2521 },
2522 {
2523 .cmd = MACSEC_CMD_DEL_RXSA,
2524 .doit = macsec_del_rxsa,
2525 .policy = macsec_genl_policy,
2526 .flags = GENL_ADMIN_PERM,
2527 },
2528 {
2529 .cmd = MACSEC_CMD_UPD_RXSA,
2530 .doit = macsec_upd_rxsa,
2531 .policy = macsec_genl_policy,
2532 .flags = GENL_ADMIN_PERM,
2533 },
2534};
2535
2536static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
2537 struct net_device *dev)
2538{
2539 struct macsec_dev *macsec = netdev_priv(dev);
2540 struct macsec_secy *secy = &macsec->secy;
2541 struct pcpu_secy_stats *secy_stats;
2542 int ret, len;
2543
2544 /* 10.5 */
2545 if (!secy->protect_frames) {
2546 secy_stats = this_cpu_ptr(macsec->stats);
2547 u64_stats_update_begin(&secy_stats->syncp);
2548 secy_stats->stats.OutPktsUntagged++;
2549 u64_stats_update_end(&secy_stats->syncp);
2550 len = skb->len;
2551 ret = dev_queue_xmit(skb);
2552 count_tx(dev, ret, len);
2553 return ret;
2554 }
2555
2556 if (!secy->operational) {
2557 kfree_skb(skb);
2558 dev->stats.tx_dropped++;
2559 return NETDEV_TX_OK;
2560 }
2561
2562 skb = macsec_encrypt(skb, dev);
2563 if (IS_ERR(skb)) {
2564 if (PTR_ERR(skb) != -EINPROGRESS)
2565 dev->stats.tx_dropped++;
2566 return NETDEV_TX_OK;
2567 }
2568
2569 macsec_count_tx(skb, &macsec->secy.tx_sc, macsec_skb_cb(skb)->tx_sa);
2570
2571 macsec_encrypt_finish(skb, dev);
2572 len = skb->len;
2573 ret = dev_queue_xmit(skb);
2574 count_tx(dev, ret, len);
2575 return ret;
2576}
2577
2578#define MACSEC_FEATURES \
2579 (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
2580static int macsec_dev_init(struct net_device *dev)
2581{
2582 struct macsec_dev *macsec = macsec_priv(dev);
2583 struct net_device *real_dev = macsec->real_dev;
2584
2585 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
2586 if (!dev->tstats)
2587 return -ENOMEM;
2588
2589 dev->features = real_dev->features & MACSEC_FEATURES;
2590 dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
2591
2592 dev->needed_headroom = real_dev->needed_headroom +
2593 MACSEC_NEEDED_HEADROOM;
2594 dev->needed_tailroom = real_dev->needed_tailroom +
2595 MACSEC_NEEDED_TAILROOM;
2596
2597 if (is_zero_ether_addr(dev->dev_addr))
2598 eth_hw_addr_inherit(dev, real_dev);
2599 if (is_zero_ether_addr(dev->broadcast))
2600 memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
2601
2602 return 0;
2603}
2604
2605static void macsec_dev_uninit(struct net_device *dev)
2606{
2607 free_percpu(dev->tstats);
2608}
2609
2610static netdev_features_t macsec_fix_features(struct net_device *dev,
2611 netdev_features_t features)
2612{
2613 struct macsec_dev *macsec = macsec_priv(dev);
2614 struct net_device *real_dev = macsec->real_dev;
2615
2616 features &= real_dev->features & MACSEC_FEATURES;
2617 features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
2618
2619 return features;
2620}
2621
2622static int macsec_dev_open(struct net_device *dev)
2623{
2624 struct macsec_dev *macsec = macsec_priv(dev);
2625 struct net_device *real_dev = macsec->real_dev;
2626 int err;
2627
2628 if (!(real_dev->flags & IFF_UP))
2629 return -ENETDOWN;
2630
2631 err = dev_uc_add(real_dev, dev->dev_addr);
2632 if (err < 0)
2633 return err;
2634
2635 if (dev->flags & IFF_ALLMULTI) {
2636 err = dev_set_allmulti(real_dev, 1);
2637 if (err < 0)
2638 goto del_unicast;
2639 }
2640
2641 if (dev->flags & IFF_PROMISC) {
2642 err = dev_set_promiscuity(real_dev, 1);
2643 if (err < 0)
2644 goto clear_allmulti;
2645 }
2646
2647 if (netif_carrier_ok(real_dev))
2648 netif_carrier_on(dev);
2649
2650 return 0;
2651clear_allmulti:
2652 if (dev->flags & IFF_ALLMULTI)
2653 dev_set_allmulti(real_dev, -1);
2654del_unicast:
2655 dev_uc_del(real_dev, dev->dev_addr);
2656 netif_carrier_off(dev);
2657 return err;
2658}
2659
2660static int macsec_dev_stop(struct net_device *dev)
2661{
2662 struct macsec_dev *macsec = macsec_priv(dev);
2663 struct net_device *real_dev = macsec->real_dev;
2664
2665 netif_carrier_off(dev);
2666
2667 dev_mc_unsync(real_dev, dev);
2668 dev_uc_unsync(real_dev, dev);
2669
2670 if (dev->flags & IFF_ALLMULTI)
2671 dev_set_allmulti(real_dev, -1);
2672
2673 if (dev->flags & IFF_PROMISC)
2674 dev_set_promiscuity(real_dev, -1);
2675
2676 dev_uc_del(real_dev, dev->dev_addr);
2677
2678 return 0;
2679}
2680
2681static void macsec_dev_change_rx_flags(struct net_device *dev, int change)
2682{
2683 struct net_device *real_dev = macsec_priv(dev)->real_dev;
2684
2685 if (!(dev->flags & IFF_UP))
2686 return;
2687
2688 if (change & IFF_ALLMULTI)
2689 dev_set_allmulti(real_dev, dev->flags & IFF_ALLMULTI ? 1 : -1);
2690
2691 if (change & IFF_PROMISC)
2692 dev_set_promiscuity(real_dev,
2693 dev->flags & IFF_PROMISC ? 1 : -1);
2694}
2695
2696static void macsec_dev_set_rx_mode(struct net_device *dev)
2697{
2698 struct net_device *real_dev = macsec_priv(dev)->real_dev;
2699
2700 dev_mc_sync(real_dev, dev);
2701 dev_uc_sync(real_dev, dev);
2702}
2703
2704static int macsec_set_mac_address(struct net_device *dev, void *p)
2705{
2706 struct macsec_dev *macsec = macsec_priv(dev);
2707 struct net_device *real_dev = macsec->real_dev;
2708 struct sockaddr *addr = p;
2709 int err;
2710
2711 if (!is_valid_ether_addr(addr->sa_data))
2712 return -EADDRNOTAVAIL;
2713
2714 if (!(dev->flags & IFF_UP))
2715 goto out;
2716
2717 err = dev_uc_add(real_dev, addr->sa_data);
2718 if (err < 0)
2719 return err;
2720
2721 dev_uc_del(real_dev, dev->dev_addr);
2722
2723out:
2724 ether_addr_copy(dev->dev_addr, addr->sa_data);
2725 return 0;
2726}
2727
2728static int macsec_change_mtu(struct net_device *dev, int new_mtu)
2729{
2730 struct macsec_dev *macsec = macsec_priv(dev);
2731 unsigned int extra = macsec->secy.icv_len + macsec_extra_len(true);
2732
2733 if (macsec->real_dev->mtu - extra < new_mtu)
2734 return -ERANGE;
2735
2736 dev->mtu = new_mtu;
2737
2738 return 0;
2739}
2740
2741static struct rtnl_link_stats64 *macsec_get_stats64(struct net_device *dev,
2742 struct rtnl_link_stats64 *s)
2743{
2744 int cpu;
2745
2746 if (!dev->tstats)
2747 return s;
2748
2749 for_each_possible_cpu(cpu) {
2750 struct pcpu_sw_netstats *stats;
2751 struct pcpu_sw_netstats tmp;
2752 int start;
2753
2754 stats = per_cpu_ptr(dev->tstats, cpu);
2755 do {
2756 start = u64_stats_fetch_begin_irq(&stats->syncp);
2757 tmp.rx_packets = stats->rx_packets;
2758 tmp.rx_bytes = stats->rx_bytes;
2759 tmp.tx_packets = stats->tx_packets;
2760 tmp.tx_bytes = stats->tx_bytes;
2761 } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
2762
2763 s->rx_packets += tmp.rx_packets;
2764 s->rx_bytes += tmp.rx_bytes;
2765 s->tx_packets += tmp.tx_packets;
2766 s->tx_bytes += tmp.tx_bytes;
2767 }
2768
2769 s->rx_dropped = dev->stats.rx_dropped;
2770 s->tx_dropped = dev->stats.tx_dropped;
2771
2772 return s;
2773}
2774
2775static int macsec_get_iflink(const struct net_device *dev)
2776{
2777 return macsec_priv(dev)->real_dev->ifindex;
2778}
2779
2780static const struct net_device_ops macsec_netdev_ops = {
2781 .ndo_init = macsec_dev_init,
2782 .ndo_uninit = macsec_dev_uninit,
2783 .ndo_open = macsec_dev_open,
2784 .ndo_stop = macsec_dev_stop,
2785 .ndo_fix_features = macsec_fix_features,
2786 .ndo_change_mtu = macsec_change_mtu,
2787 .ndo_set_rx_mode = macsec_dev_set_rx_mode,
2788 .ndo_change_rx_flags = macsec_dev_change_rx_flags,
2789 .ndo_set_mac_address = macsec_set_mac_address,
2790 .ndo_start_xmit = macsec_start_xmit,
2791 .ndo_get_stats64 = macsec_get_stats64,
2792 .ndo_get_iflink = macsec_get_iflink,
2793};
2794
2795static const struct device_type macsec_type = {
2796 .name = "macsec",
2797};
2798
2799static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = {
2800 [IFLA_MACSEC_SCI] = { .type = NLA_U64 },
2801 [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 },
2802 [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 },
2803 [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 },
2804 [IFLA_MACSEC_ENCODING_SA] = { .type = NLA_U8 },
2805 [IFLA_MACSEC_ENCRYPT] = { .type = NLA_U8 },
2806 [IFLA_MACSEC_PROTECT] = { .type = NLA_U8 },
2807 [IFLA_MACSEC_INC_SCI] = { .type = NLA_U8 },
2808 [IFLA_MACSEC_ES] = { .type = NLA_U8 },
2809 [IFLA_MACSEC_SCB] = { .type = NLA_U8 },
2810 [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
2811 [IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
2812};
2813
2814static void macsec_free_netdev(struct net_device *dev)
2815{
2816 struct macsec_dev *macsec = macsec_priv(dev);
2817 struct net_device *real_dev = macsec->real_dev;
2818
2819 free_percpu(macsec->stats);
2820 free_percpu(macsec->secy.tx_sc.stats);
2821
2822 dev_put(real_dev);
2823 free_netdev(dev);
2824}
2825
2826static void macsec_setup(struct net_device *dev)
2827{
2828 ether_setup(dev);
2829 dev->tx_queue_len = 0;
2830 dev->netdev_ops = &macsec_netdev_ops;
2831 dev->destructor = macsec_free_netdev;
2832
2833 eth_zero_addr(dev->broadcast);
2834}
2835
2836static void macsec_changelink_common(struct net_device *dev,
2837 struct nlattr *data[])
2838{
2839 struct macsec_secy *secy;
2840 struct macsec_tx_sc *tx_sc;
2841
2842 secy = &macsec_priv(dev)->secy;
2843 tx_sc = &secy->tx_sc;
2844
2845 if (data[IFLA_MACSEC_ENCODING_SA]) {
2846 struct macsec_tx_sa *tx_sa;
2847
2848 tx_sc->encoding_sa = nla_get_u8(data[IFLA_MACSEC_ENCODING_SA]);
2849 tx_sa = rtnl_dereference(tx_sc->sa[tx_sc->encoding_sa]);
2850
2851 secy->operational = tx_sa && tx_sa->active;
2852 }
2853
2854 if (data[IFLA_MACSEC_WINDOW])
2855 secy->replay_window = nla_get_u32(data[IFLA_MACSEC_WINDOW]);
2856
2857 if (data[IFLA_MACSEC_ENCRYPT])
2858 tx_sc->encrypt = !!nla_get_u8(data[IFLA_MACSEC_ENCRYPT]);
2859
2860 if (data[IFLA_MACSEC_PROTECT])
2861 secy->protect_frames = !!nla_get_u8(data[IFLA_MACSEC_PROTECT]);
2862
2863 if (data[IFLA_MACSEC_INC_SCI])
2864 tx_sc->send_sci = !!nla_get_u8(data[IFLA_MACSEC_INC_SCI]);
2865
2866 if (data[IFLA_MACSEC_ES])
2867 tx_sc->end_station = !!nla_get_u8(data[IFLA_MACSEC_ES]);
2868
2869 if (data[IFLA_MACSEC_SCB])
2870 tx_sc->scb = !!nla_get_u8(data[IFLA_MACSEC_SCB]);
2871
2872 if (data[IFLA_MACSEC_REPLAY_PROTECT])
2873 secy->replay_protect = !!nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT]);
2874
2875 if (data[IFLA_MACSEC_VALIDATION])
2876 secy->validate_frames = nla_get_u8(data[IFLA_MACSEC_VALIDATION]);
2877}
2878
2879static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
2880 struct nlattr *data[])
2881{
2882 if (!data)
2883 return 0;
2884
2885 if (data[IFLA_MACSEC_CIPHER_SUITE] ||
2886 data[IFLA_MACSEC_ICV_LEN] ||
2887 data[IFLA_MACSEC_SCI] ||
2888 data[IFLA_MACSEC_PORT])
2889 return -EINVAL;
2890
2891 macsec_changelink_common(dev, data);
2892
2893 return 0;
2894}
2895
2896static void macsec_del_dev(struct macsec_dev *macsec)
2897{
2898 int i;
2899
2900 while (macsec->secy.rx_sc) {
2901 struct macsec_rx_sc *rx_sc = rtnl_dereference(macsec->secy.rx_sc);
2902
2903 rcu_assign_pointer(macsec->secy.rx_sc, rx_sc->next);
2904 free_rx_sc(rx_sc);
2905 }
2906
2907 for (i = 0; i < MACSEC_NUM_AN; i++) {
2908 struct macsec_tx_sa *sa = rtnl_dereference(macsec->secy.tx_sc.sa[i]);
2909
2910 if (sa) {
2911 RCU_INIT_POINTER(macsec->secy.tx_sc.sa[i], NULL);
2912 clear_tx_sa(sa);
2913 }
2914 }
2915}
2916
2917static void macsec_dellink(struct net_device *dev, struct list_head *head)
2918{
2919 struct macsec_dev *macsec = macsec_priv(dev);
2920 struct net_device *real_dev = macsec->real_dev;
2921 struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev);
2922
2923 unregister_netdevice_queue(dev, head);
2924 list_del_rcu(&macsec->secys);
2925 if (list_empty(&rxd->secys))
2926 netdev_rx_handler_unregister(real_dev);
2927
2928 macsec_del_dev(macsec);
2929}
2930
2931static int register_macsec_dev(struct net_device *real_dev,
2932 struct net_device *dev)
2933{
2934 struct macsec_dev *macsec = macsec_priv(dev);
2935 struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev);
2936
2937 if (!rxd) {
2938 int err;
2939
2940 rxd = kmalloc(sizeof(*rxd), GFP_KERNEL);
2941 if (!rxd)
2942 return -ENOMEM;
2943
2944 INIT_LIST_HEAD(&rxd->secys);
2945
2946 err = netdev_rx_handler_register(real_dev, macsec_handle_frame,
2947 rxd);
2948 if (err < 0)
2949 return err;
2950 }
2951
2952 list_add_tail_rcu(&macsec->secys, &rxd->secys);
2953 return 0;
2954}
2955
2956static bool sci_exists(struct net_device *dev, sci_t sci)
2957{
2958 struct macsec_rxh_data *rxd = macsec_data_rtnl(dev);
2959 struct macsec_dev *macsec;
2960
2961 list_for_each_entry(macsec, &rxd->secys, secys) {
2962 if (macsec->secy.sci == sci)
2963 return true;
2964 }
2965
2966 return false;
2967}
2968
2969static sci_t dev_to_sci(struct net_device *dev, __be16 port)
2970{
2971 return make_sci(dev->dev_addr, port);
2972}
2973
2974static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
2975{
2976 struct macsec_dev *macsec = macsec_priv(dev);
2977 struct macsec_secy *secy = &macsec->secy;
2978
2979 macsec->stats = netdev_alloc_pcpu_stats(struct pcpu_secy_stats);
2980 if (!macsec->stats)
2981 return -ENOMEM;
2982
2983 secy->tx_sc.stats = netdev_alloc_pcpu_stats(struct pcpu_tx_sc_stats);
2984 if (!secy->tx_sc.stats) {
2985 free_percpu(macsec->stats);
2986 return -ENOMEM;
2987 }
2988
2989 if (sci == MACSEC_UNDEF_SCI)
2990 sci = dev_to_sci(dev, MACSEC_PORT_ES);
2991
2992 secy->netdev = dev;
2993 secy->operational = true;
2994 secy->key_len = DEFAULT_SAK_LEN;
2995 secy->icv_len = icv_len;
2996 secy->validate_frames = MACSEC_VALIDATE_DEFAULT;
2997 secy->protect_frames = true;
2998 secy->replay_protect = false;
2999
3000 secy->sci = sci;
3001 secy->tx_sc.active = true;
3002 secy->tx_sc.encoding_sa = DEFAULT_ENCODING_SA;
3003 secy->tx_sc.encrypt = DEFAULT_ENCRYPT;
3004 secy->tx_sc.send_sci = DEFAULT_SEND_SCI;
3005 secy->tx_sc.end_station = false;
3006 secy->tx_sc.scb = false;
3007
3008 return 0;
3009}
3010
3011static int macsec_newlink(struct net *net, struct net_device *dev,
3012 struct nlattr *tb[], struct nlattr *data[])
3013{
3014 struct macsec_dev *macsec = macsec_priv(dev);
3015 struct net_device *real_dev;
3016 int err;
3017 sci_t sci;
3018 u8 icv_len = DEFAULT_ICV_LEN;
3019 rx_handler_func_t *rx_handler;
3020
3021 if (!tb[IFLA_LINK])
3022 return -EINVAL;
3023 real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
3024 if (!real_dev)
3025 return -ENODEV;
3026
3027 dev->priv_flags |= IFF_MACSEC;
3028
3029 macsec->real_dev = real_dev;
3030
3031 if (data && data[IFLA_MACSEC_ICV_LEN])
3032 icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]);
3033 dev->mtu = real_dev->mtu - icv_len - macsec_extra_len(true);
3034
3035 rx_handler = rtnl_dereference(real_dev->rx_handler);
3036 if (rx_handler && rx_handler != macsec_handle_frame)
3037 return -EBUSY;
3038
3039 err = register_netdevice(dev);
3040 if (err < 0)
3041 return err;
3042
3043 /* need to be already registered so that ->init has run and
3044 * the MAC addr is set
3045 */
3046 if (data && data[IFLA_MACSEC_SCI])
3047 sci = nla_get_sci(data[IFLA_MACSEC_SCI]);
3048 else if (data && data[IFLA_MACSEC_PORT])
3049 sci = dev_to_sci(dev, nla_get_be16(data[IFLA_MACSEC_PORT]));
3050 else
3051 sci = dev_to_sci(dev, MACSEC_PORT_ES);
3052
3053 if (rx_handler && sci_exists(real_dev, sci)) {
3054 err = -EBUSY;
3055 goto unregister;
3056 }
3057
3058 err = macsec_add_dev(dev, sci, icv_len);
3059 if (err)
3060 goto unregister;
3061
3062 if (data)
3063 macsec_changelink_common(dev, data);
3064
3065 err = register_macsec_dev(real_dev, dev);
3066 if (err < 0)
3067 goto del_dev;
3068
3069 dev_hold(real_dev);
3070
3071 return 0;
3072
3073del_dev:
3074 macsec_del_dev(macsec);
3075unregister:
3076 unregister_netdevice(dev);
3077 return err;
3078}
3079
3080static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[])
3081{
3082 u64 csid = DEFAULT_CIPHER_ID;
3083 u8 icv_len = DEFAULT_ICV_LEN;
3084 int flag;
3085 bool es, scb, sci;
3086
3087 if (!data)
3088 return 0;
3089
3090 if (data[IFLA_MACSEC_CIPHER_SUITE])
3091 csid = nla_get_u64(data[IFLA_MACSEC_CIPHER_SUITE]);
3092
3093 if (data[IFLA_MACSEC_ICV_LEN])
3094 icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]);
3095
3096 switch (csid) {
3097 case DEFAULT_CIPHER_ID:
3098 case DEFAULT_CIPHER_ALT:
3099 if (icv_len < MACSEC_MIN_ICV_LEN ||
3100 icv_len > MACSEC_MAX_ICV_LEN)
3101 return -EINVAL;
3102 break;
3103 default:
3104 return -EINVAL;
3105 }
3106
3107 if (data[IFLA_MACSEC_ENCODING_SA]) {
3108 if (nla_get_u8(data[IFLA_MACSEC_ENCODING_SA]) >= MACSEC_NUM_AN)
3109 return -EINVAL;
3110 }
3111
3112 for (flag = IFLA_MACSEC_ENCODING_SA + 1;
3113 flag < IFLA_MACSEC_VALIDATION;
3114 flag++) {
3115 if (data[flag]) {
3116 if (nla_get_u8(data[flag]) > 1)
3117 return -EINVAL;
3118 }
3119 }
3120
3121 es = data[IFLA_MACSEC_ES] ? nla_get_u8(data[IFLA_MACSEC_ES]) : false;
3122 sci = data[IFLA_MACSEC_INC_SCI] ? nla_get_u8(data[IFLA_MACSEC_INC_SCI]) : false;
3123 scb = data[IFLA_MACSEC_SCB] ? nla_get_u8(data[IFLA_MACSEC_SCB]) : false;
3124
3125 if ((sci && (scb || es)) || (scb && es))
3126 return -EINVAL;
3127
3128 if (data[IFLA_MACSEC_VALIDATION] &&
3129 nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX)
3130 return -EINVAL;
3131
3132 if ((data[IFLA_MACSEC_PROTECT] &&
3133 nla_get_u8(data[IFLA_MACSEC_PROTECT])) &&
3134 !data[IFLA_MACSEC_WINDOW])
3135 return -EINVAL;
3136
3137 return 0;
3138}
3139
3140static struct net *macsec_get_link_net(const struct net_device *dev)
3141{
3142 return dev_net(macsec_priv(dev)->real_dev);
3143}
3144
3145static size_t macsec_get_size(const struct net_device *dev)
3146{
3147 return 0 +
3148 nla_total_size(8) + /* SCI */
3149 nla_total_size(1) + /* ICV_LEN */
3150 nla_total_size(8) + /* CIPHER_SUITE */
3151 nla_total_size(4) + /* WINDOW */
3152 nla_total_size(1) + /* ENCODING_SA */
3153 nla_total_size(1) + /* ENCRYPT */
3154 nla_total_size(1) + /* PROTECT */
3155 nla_total_size(1) + /* INC_SCI */
3156 nla_total_size(1) + /* ES */
3157 nla_total_size(1) + /* SCB */
3158 nla_total_size(1) + /* REPLAY_PROTECT */
3159 nla_total_size(1) + /* VALIDATION */
3160 0;
3161}
3162
3163static int macsec_fill_info(struct sk_buff *skb,
3164 const struct net_device *dev)
3165{
3166 struct macsec_secy *secy = &macsec_priv(dev)->secy;
3167 struct macsec_tx_sc *tx_sc = &secy->tx_sc;
3168
3169 if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) ||
3170 nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) ||
3171 nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, DEFAULT_CIPHER_ID) ||
3172 nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) ||
3173 nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) ||
3174 nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) ||
3175 nla_put_u8(skb, IFLA_MACSEC_INC_SCI, tx_sc->send_sci) ||
3176 nla_put_u8(skb, IFLA_MACSEC_ES, tx_sc->end_station) ||
3177 nla_put_u8(skb, IFLA_MACSEC_SCB, tx_sc->scb) ||
3178 nla_put_u8(skb, IFLA_MACSEC_REPLAY_PROTECT, secy->replay_protect) ||
3179 nla_put_u8(skb, IFLA_MACSEC_VALIDATION, secy->validate_frames) ||
3180 0)
3181 goto nla_put_failure;
3182
3183 if (secy->replay_protect) {
3184 if (nla_put_u32(skb, IFLA_MACSEC_WINDOW, secy->replay_window))
3185 goto nla_put_failure;
3186 }
3187
3188 return 0;
3189
3190nla_put_failure:
3191 return -EMSGSIZE;
3192}
3193
3194static struct rtnl_link_ops macsec_link_ops __read_mostly = {
3195 .kind = "macsec",
3196 .priv_size = sizeof(struct macsec_dev),
3197 .maxtype = IFLA_MACSEC_MAX,
3198 .policy = macsec_rtnl_policy,
3199 .setup = macsec_setup,
3200 .validate = macsec_validate_attr,
3201 .newlink = macsec_newlink,
3202 .changelink = macsec_changelink,
3203 .dellink = macsec_dellink,
3204 .get_size = macsec_get_size,
3205 .fill_info = macsec_fill_info,
3206 .get_link_net = macsec_get_link_net,
3207};
3208
3209static bool is_macsec_master(struct net_device *dev)
3210{
3211 return rcu_access_pointer(dev->rx_handler) == macsec_handle_frame;
3212}
3213
3214static int macsec_notify(struct notifier_block *this, unsigned long event,
3215 void *ptr)
3216{
3217 struct net_device *real_dev = netdev_notifier_info_to_dev(ptr);
3218 LIST_HEAD(head);
3219
3220 if (!is_macsec_master(real_dev))
3221 return NOTIFY_DONE;
3222
3223 switch (event) {
3224 case NETDEV_UNREGISTER: {
3225 struct macsec_dev *m, *n;
3226 struct macsec_rxh_data *rxd;
3227
3228 rxd = macsec_data_rtnl(real_dev);
3229 list_for_each_entry_safe(m, n, &rxd->secys, secys) {
3230 macsec_dellink(m->secy.netdev, &head);
3231 }
3232 unregister_netdevice_many(&head);
3233 break;
3234 }
3235 case NETDEV_CHANGEMTU: {
3236 struct macsec_dev *m;
3237 struct macsec_rxh_data *rxd;
3238
3239 rxd = macsec_data_rtnl(real_dev);
3240 list_for_each_entry(m, &rxd->secys, secys) {
3241 struct net_device *dev = m->secy.netdev;
3242 unsigned int mtu = real_dev->mtu - (m->secy.icv_len +
3243 macsec_extra_len(true));
3244
3245 if (dev->mtu > mtu)
3246 dev_set_mtu(dev, mtu);
3247 }
3248 }
3249 }
3250
3251 return NOTIFY_OK;
3252}
3253
3254static struct notifier_block macsec_notifier = {
3255 .notifier_call = macsec_notify,
3256};
3257
3258static int __init macsec_init(void)
3259{
3260 int err;
3261
3262 pr_info("MACsec IEEE 802.1AE\n");
3263 err = register_netdevice_notifier(&macsec_notifier);
3264 if (err)
3265 return err;
3266
3267 err = rtnl_link_register(&macsec_link_ops);
3268 if (err)
3269 goto notifier;
3270
3271 err = genl_register_family_with_ops(&macsec_fam, macsec_genl_ops);
3272 if (err)
3273 goto rtnl;
3274
3275 return 0;
3276
3277rtnl:
3278 rtnl_link_unregister(&macsec_link_ops);
3279notifier:
3280 unregister_netdevice_notifier(&macsec_notifier);
3281 return err;
3282}
3283
3284static void __exit macsec_exit(void)
3285{
3286 genl_unregister_family(&macsec_fam);
3287 rtnl_link_unregister(&macsec_link_ops);
3288 unregister_netdevice_notifier(&macsec_notifier);
3289}
3290
3291module_init(macsec_init);
3292module_exit(macsec_exit);
3293
3294MODULE_ALIAS_RTNL_LINK("macsec");
3295
3296MODULE_DESCRIPTION("MACsec IEEE 802.1AE");
3297MODULE_LICENSE("GPL v2");
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 41df0b450757..be693b34662f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1328,6 +1328,7 @@ struct net_device_ops {
1328 * @IFF_RXFH_CONFIGURED: device has had Rx Flow indirection table configured 1328 * @IFF_RXFH_CONFIGURED: device has had Rx Flow indirection table configured
1329 * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external 1329 * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external
1330 * entity (i.e. the master device for bridged veth) 1330 * entity (i.e. the master device for bridged veth)
1331 * @IFF_MACSEC: device is a MACsec device
1331 */ 1332 */
1332enum netdev_priv_flags { 1333enum netdev_priv_flags {
1333 IFF_802_1Q_VLAN = 1<<0, 1334 IFF_802_1Q_VLAN = 1<<0,
@@ -1357,6 +1358,7 @@ enum netdev_priv_flags {
1357 IFF_TEAM = 1<<24, 1358 IFF_TEAM = 1<<24,
1358 IFF_RXFH_CONFIGURED = 1<<25, 1359 IFF_RXFH_CONFIGURED = 1<<25,
1359 IFF_PHONY_HEADROOM = 1<<26, 1360 IFF_PHONY_HEADROOM = 1<<26,
1361 IFF_MACSEC = 1<<27,
1360}; 1362};
1361 1363
1362#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN 1364#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
@@ -1385,6 +1387,7 @@ enum netdev_priv_flags {
1385#define IFF_L3MDEV_SLAVE IFF_L3MDEV_SLAVE 1387#define IFF_L3MDEV_SLAVE IFF_L3MDEV_SLAVE
1386#define IFF_TEAM IFF_TEAM 1388#define IFF_TEAM IFF_TEAM
1387#define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED 1389#define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED
1390#define IFF_MACSEC IFF_MACSEC
1388 1391
1389/** 1392/**
1390 * struct net_device - The DEVICE structure. 1393 * struct net_device - The DEVICE structure.
@@ -4045,6 +4048,11 @@ static inline void skb_gso_error_unwind(struct sk_buff *skb, __be16 protocol,
4045 skb->mac_len = mac_len; 4048 skb->mac_len = mac_len;
4046} 4049}
4047 4050
4051static inline bool netif_is_macsec(const struct net_device *dev)
4052{
4053 return dev->priv_flags & IFF_MACSEC;
4054}
4055
4048static inline bool netif_is_macvlan(const struct net_device *dev) 4056static inline bool netif_is_macvlan(const struct net_device *dev)
4049{ 4057{
4050 return dev->priv_flags & IFF_MACVLAN; 4058 return dev->priv_flags & IFF_MACVLAN;
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index ebd10e624598..e25ebcfbcb48 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -173,6 +173,7 @@ header-y += if_hippi.h
173header-y += if_infiniband.h 173header-y += if_infiniband.h
174header-y += if_link.h 174header-y += if_link.h
175header-y += if_ltalk.h 175header-y += if_ltalk.h
176header-y += if_macsec.h
176header-y += if_packet.h 177header-y += if_packet.h
177header-y += if_phonet.h 178header-y += if_phonet.h
178header-y += if_plip.h 179header-y += if_plip.h
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index ea9221b0331a..4a93051c578c 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -83,6 +83,7 @@
83#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ 83#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
84#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */ 84#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
85#define ETH_P_TIPC 0x88CA /* TIPC */ 85#define ETH_P_TIPC 0x88CA /* TIPC */
86#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
86#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ 87#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
87#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */ 88#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
88#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ 89#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 249eef9a21bd..8e3f88fa5b59 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -413,6 +413,35 @@ enum {
413 413
414#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1) 414#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
415 415
416/* MACSEC section */
417enum {
418 IFLA_MACSEC_UNSPEC,
419 IFLA_MACSEC_SCI,
420 IFLA_MACSEC_PORT,
421 IFLA_MACSEC_ICV_LEN,
422 IFLA_MACSEC_CIPHER_SUITE,
423 IFLA_MACSEC_WINDOW,
424 IFLA_MACSEC_ENCODING_SA,
425 IFLA_MACSEC_ENCRYPT,
426 IFLA_MACSEC_PROTECT,
427 IFLA_MACSEC_INC_SCI,
428 IFLA_MACSEC_ES,
429 IFLA_MACSEC_SCB,
430 IFLA_MACSEC_REPLAY_PROTECT,
431 IFLA_MACSEC_VALIDATION,
432 __IFLA_MACSEC_MAX,
433};
434
435#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
436
437enum macsec_validation_type {
438 MACSEC_VALIDATE_DISABLED = 0,
439 MACSEC_VALIDATE_CHECK = 1,
440 MACSEC_VALIDATE_STRICT = 2,
441 __MACSEC_VALIDATE_END,
442 MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
443};
444
416/* IPVLAN section */ 445/* IPVLAN section */
417enum { 446enum {
418 IFLA_IPVLAN_UNSPEC, 447 IFLA_IPVLAN_UNSPEC,
diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h
new file mode 100644
index 000000000000..26b0d1e3e3e7
--- /dev/null
+++ b/include/uapi/linux/if_macsec.h
@@ -0,0 +1,161 @@
1/*
2 * include/uapi/linux/if_macsec.h - MACsec device
3 *
4 * Copyright (c) 2015 Sabrina Dubroca <sd@queasysnail.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef _UAPI_MACSEC_H
13#define _UAPI_MACSEC_H
14
15#include <linux/types.h>
16
17#define MACSEC_GENL_NAME "macsec"
18#define MACSEC_GENL_VERSION 1
19
20#define MACSEC_MAX_KEY_LEN 128
21
22#define DEFAULT_CIPHER_ID 0x0080020001000001ULL
23#define DEFAULT_CIPHER_ALT 0x0080C20001000001ULL
24
25#define MACSEC_MIN_ICV_LEN 8
26#define MACSEC_MAX_ICV_LEN 32
27
28enum macsec_attrs {
29 MACSEC_ATTR_UNSPEC,
30 MACSEC_ATTR_IFINDEX, /* u32, ifindex of the MACsec netdevice */
31 MACSEC_ATTR_RXSC_CONFIG, /* config, nested macsec_rxsc_attrs */
32 MACSEC_ATTR_SA_CONFIG, /* config, nested macsec_sa_attrs */
33 MACSEC_ATTR_SECY, /* dump, nested macsec_secy_attrs */
34 MACSEC_ATTR_TXSA_LIST, /* dump, nested, macsec_sa_attrs for each TXSA */
35 MACSEC_ATTR_RXSC_LIST, /* dump, nested, macsec_rxsc_attrs for each RXSC */
36 MACSEC_ATTR_TXSC_STATS, /* dump, nested, macsec_txsc_stats_attr */
37 MACSEC_ATTR_SECY_STATS, /* dump, nested, macsec_secy_stats_attr */
38 __MACSEC_ATTR_END,
39 NUM_MACSEC_ATTR = __MACSEC_ATTR_END,
40 MACSEC_ATTR_MAX = __MACSEC_ATTR_END - 1,
41};
42
43enum macsec_secy_attrs {
44 MACSEC_SECY_ATTR_UNSPEC,
45 MACSEC_SECY_ATTR_SCI,
46 MACSEC_SECY_ATTR_ENCODING_SA,
47 MACSEC_SECY_ATTR_WINDOW,
48 MACSEC_SECY_ATTR_CIPHER_SUITE,
49 MACSEC_SECY_ATTR_ICV_LEN,
50 MACSEC_SECY_ATTR_PROTECT,
51 MACSEC_SECY_ATTR_REPLAY,
52 MACSEC_SECY_ATTR_OPER,
53 MACSEC_SECY_ATTR_VALIDATE,
54 MACSEC_SECY_ATTR_ENCRYPT,
55 MACSEC_SECY_ATTR_INC_SCI,
56 MACSEC_SECY_ATTR_ES,
57 MACSEC_SECY_ATTR_SCB,
58 __MACSEC_SECY_ATTR_END,
59 NUM_MACSEC_SECY_ATTR = __MACSEC_SECY_ATTR_END,
60 MACSEC_SECY_ATTR_MAX = __MACSEC_SECY_ATTR_END - 1,
61};
62
63enum macsec_rxsc_attrs {
64 MACSEC_RXSC_ATTR_UNSPEC,
65 MACSEC_RXSC_ATTR_SCI, /* config/dump, u64 */
66 MACSEC_RXSC_ATTR_ACTIVE, /* config/dump, u8 0..1 */
67 MACSEC_RXSC_ATTR_SA_LIST, /* dump, nested */
68 MACSEC_RXSC_ATTR_STATS, /* dump, nested, macsec_rxsc_stats_attr */
69 __MACSEC_RXSC_ATTR_END,
70 NUM_MACSEC_RXSC_ATTR = __MACSEC_RXSC_ATTR_END,
71 MACSEC_RXSC_ATTR_MAX = __MACSEC_RXSC_ATTR_END - 1,
72};
73
74enum macsec_sa_attrs {
75 MACSEC_SA_ATTR_UNSPEC,
76 MACSEC_SA_ATTR_AN, /* config/dump, u8 0..3 */
77 MACSEC_SA_ATTR_ACTIVE, /* config/dump, u8 0..1 */
78 MACSEC_SA_ATTR_PN, /* config/dump, u32 */
79 MACSEC_SA_ATTR_KEY, /* config, data */
80 MACSEC_SA_ATTR_KEYID, /* config/dump, u64 */
81 MACSEC_SA_ATTR_STATS, /* dump, nested, macsec_sa_stats_attr */
82 __MACSEC_SA_ATTR_END,
83 NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END,
84 MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END - 1,
85};
86
87enum macsec_nl_commands {
88 MACSEC_CMD_GET_TXSC,
89 MACSEC_CMD_ADD_RXSC,
90 MACSEC_CMD_DEL_RXSC,
91 MACSEC_CMD_UPD_RXSC,
92 MACSEC_CMD_ADD_TXSA,
93 MACSEC_CMD_DEL_TXSA,
94 MACSEC_CMD_UPD_TXSA,
95 MACSEC_CMD_ADD_RXSA,
96 MACSEC_CMD_DEL_RXSA,
97 MACSEC_CMD_UPD_RXSA,
98};
99
100/* u64 per-RXSC stats */
101enum macsec_rxsc_stats_attr {
102 MACSEC_RXSC_STATS_ATTR_UNSPEC,
103 MACSEC_RXSC_STATS_ATTR_IN_OCTETS_VALIDATED,
104 MACSEC_RXSC_STATS_ATTR_IN_OCTETS_DECRYPTED,
105 MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNCHECKED,
106 MACSEC_RXSC_STATS_ATTR_IN_PKTS_DELAYED,
107 MACSEC_RXSC_STATS_ATTR_IN_PKTS_OK,
108 MACSEC_RXSC_STATS_ATTR_IN_PKTS_INVALID,
109 MACSEC_RXSC_STATS_ATTR_IN_PKTS_LATE,
110 MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_VALID,
111 MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_USING_SA,
112 MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNUSED_SA,
113 __MACSEC_RXSC_STATS_ATTR_END,
114 NUM_MACSEC_RXSC_STATS_ATTR = __MACSEC_RXSC_STATS_ATTR_END,
115 MACSEC_RXSC_STATS_ATTR_MAX = __MACSEC_RXSC_STATS_ATTR_END - 1,
116};
117
118/* u32 per-{RX,TX}SA stats */
119enum macsec_sa_stats_attr {
120 MACSEC_SA_STATS_ATTR_UNSPEC,
121 MACSEC_SA_STATS_ATTR_IN_PKTS_OK,
122 MACSEC_SA_STATS_ATTR_IN_PKTS_INVALID,
123 MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_VALID,
124 MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_USING_SA,
125 MACSEC_SA_STATS_ATTR_IN_PKTS_UNUSED_SA,
126 MACSEC_SA_STATS_ATTR_OUT_PKTS_PROTECTED,
127 MACSEC_SA_STATS_ATTR_OUT_PKTS_ENCRYPTED,
128 __MACSEC_SA_STATS_ATTR_END,
129 NUM_MACSEC_SA_STATS_ATTR = __MACSEC_SA_STATS_ATTR_END,
130 MACSEC_SA_STATS_ATTR_MAX = __MACSEC_SA_STATS_ATTR_END - 1,
131};
132
133/* u64 per-TXSC stats */
134enum macsec_txsc_stats_attr {
135 MACSEC_TXSC_STATS_ATTR_UNSPEC,
136 MACSEC_TXSC_STATS_ATTR_OUT_PKTS_PROTECTED,
137 MACSEC_TXSC_STATS_ATTR_OUT_PKTS_ENCRYPTED,
138 MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_PROTECTED,
139 MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_ENCRYPTED,
140 __MACSEC_TXSC_STATS_ATTR_END,
141 NUM_MACSEC_TXSC_STATS_ATTR = __MACSEC_TXSC_STATS_ATTR_END,
142 MACSEC_TXSC_STATS_ATTR_MAX = __MACSEC_TXSC_STATS_ATTR_END - 1,
143};
144
145/* u64 per-SecY stats */
146enum macsec_secy_stats_attr {
147 MACSEC_SECY_STATS_ATTR_UNSPEC,
148 MACSEC_SECY_STATS_ATTR_OUT_PKTS_UNTAGGED,
149 MACSEC_SECY_STATS_ATTR_IN_PKTS_UNTAGGED,
150 MACSEC_SECY_STATS_ATTR_OUT_PKTS_TOO_LONG,
151 MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_TAG,
152 MACSEC_SECY_STATS_ATTR_IN_PKTS_BAD_TAG,
153 MACSEC_SECY_STATS_ATTR_IN_PKTS_UNKNOWN_SCI,
154 MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_SCI,
155 MACSEC_SECY_STATS_ATTR_IN_PKTS_OVERRUN,
156 __MACSEC_SECY_STATS_ATTR_END,
157 NUM_MACSEC_SECY_STATS_ATTR = __MACSEC_SECY_STATS_ATTR_END,
158 MACSEC_SECY_STATS_ATTR_MAX = __MACSEC_SECY_STATS_ATTR_END - 1,
159};
160
161#endif /* _UAPI_MACSEC_H */