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