Skip to content

Commit 80f154c

Browse files
author
CKI Backport Bot
committed
macsec: MACsec SCI assignment for ES = 0
JIRA: https://issues.redhat.com/browse/RHEL-115574 commit d9816ec Author: Carlos Fernandez <carlos.fernandez@technica-engineering.de> Date: Mon Jun 9 09:26:26 2025 +0200 macsec: MACsec SCI assignment for ES = 0 According to 802.1AE standard, when ES and SC flags in TCI are zero, used SCI should be the current active SC_RX. Current code uses the header MAC address. Without this patch, when ES flag is 0 (using a bridge or switch), header MAC will not fit the SCI and MACSec frames will be discarted. In order to test this issue, MACsec link should be stablished between two interfaces, setting SC and ES flags to zero and a port identifier different than one. For example, using ip macsec tools: ip link add link $ETH0 macsec0 type macsec port 11 send_sci off end_station off ip macsec add macsec0 tx sa 0 pn 2 on key 01 $ETH1_KEY ip macsec add macsec0 rx port 11 address $ETH1_MAC ip macsec add macsec0 rx port 11 address $ETH1_MAC sa 0 pn 2 on key 02 ip link set dev macsec0 up ip link add link $ETH1 macsec1 type macsec port 11 send_sci off end_station off ip macsec add macsec1 tx sa 0 pn 2 on key 01 $ETH0_KEY ip macsec add macsec1 rx port 11 address $ETH0_MAC ip macsec add macsec1 rx port 11 address $ETH0_MAC sa 0 pn 2 on key 02 ip link set dev macsec1 up Fixes: c09440f ("macsec: introduce IEEE 802.1AE driver") Co-developed-by: Andreu Montiel <Andreu.Montiel@technica-engineering.de> Signed-off-by: Andreu Montiel <Andreu.Montiel@technica-engineering.de> Signed-off-by: Carlos Fernandez <carlos.fernandez@technica-engineering.de> Reviewed-by: Subbaraya Sundeep <sbhatta@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
1 parent 1338eff commit 80f154c

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

drivers/net/macsec.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,39 @@ static sci_t make_sci(const u8 *addr, __be16 port)
246246
return sci;
247247
}
248248

249-
static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present)
249+
static sci_t macsec_active_sci(struct macsec_secy *secy)
250250
{
251-
sci_t sci;
251+
struct macsec_rx_sc *rx_sc = rcu_dereference_bh(secy->rx_sc);
252+
253+
/* Case single RX SC */
254+
if (rx_sc && !rcu_dereference_bh(rx_sc->next))
255+
return (rx_sc->active) ? rx_sc->sci : 0;
256+
/* Case no RX SC or multiple */
257+
else
258+
return 0;
259+
}
260+
261+
static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present,
262+
struct macsec_rxh_data *rxd)
263+
{
264+
struct macsec_dev *macsec;
265+
sci_t sci = 0;
252266

253-
if (sci_present)
267+
/* SC = 1 */
268+
if (sci_present) {
254269
memcpy(&sci, hdr->secure_channel_id,
255270
sizeof(hdr->secure_channel_id));
256-
else
271+
/* SC = 0; ES = 0 */
272+
} else if ((!(hdr->tci_an & (MACSEC_TCI_ES | MACSEC_TCI_SC))) &&
273+
(list_is_singular(&rxd->secys))) {
274+
/* Only one SECY should exist on this scenario */
275+
macsec = list_first_or_null_rcu(&rxd->secys, struct macsec_dev,
276+
secys);
277+
if (macsec)
278+
return macsec_active_sci(&macsec->secy);
279+
} else {
257280
sci = make_sci(hdr->eth.h_source, MACSEC_PORT_ES);
281+
}
258282

259283
return sci;
260284
}
@@ -1108,7 +1132,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
11081132
struct macsec_rxh_data *rxd;
11091133
struct macsec_dev *macsec;
11101134
unsigned int len;
1111-
sci_t sci;
1135+
sci_t sci = 0;
11121136
u32 hdr_pn;
11131137
bool cbit;
11141138
struct pcpu_rx_sc_stats *rxsc_stats;
@@ -1155,11 +1179,14 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
11551179

11561180
macsec_skb_cb(skb)->has_sci = !!(hdr->tci_an & MACSEC_TCI_SC);
11571181
macsec_skb_cb(skb)->assoc_num = hdr->tci_an & MACSEC_AN_MASK;
1158-
sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci);
11591182

11601183
rcu_read_lock();
11611184
rxd = macsec_data_rcu(skb->dev);
11621185

1186+
sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci, rxd);
1187+
if (!sci)
1188+
goto drop_nosc;
1189+
11631190
list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
11641191
struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci);
11651192

@@ -1282,6 +1309,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
12821309
macsec_rxsa_put(rx_sa);
12831310
drop_nosa:
12841311
macsec_rxsc_put(rx_sc);
1312+
drop_nosc:
12851313
rcu_read_unlock();
12861314
drop_direct:
12871315
kfree_skb(skb);

0 commit comments

Comments
 (0)