mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
macsec: no longer rely on RTNL in macsec_fill_info()
Add READ_ONCE()/WRITE_ONCE() annotations on fields that can be changed concurrently in macsec_changelink() and macsec_update_offload(): - secy->key_len - secy->xpn - tx_sc->encoding_sa - tx_sc->encrypt - secy->protect_frames - tx_sc->send_sci - tx_sc->end_station - tx_sc->scb - secy->replay_protect - secy->validate_frames - secy->replay_window - macsec->offload This allows macsec_fill_info() to run locklessly without RTNL. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Sabrina Dubroca <sd@queasysnail.net> Cc: Andrew Lunn <andrew+netdev@lunn.ch> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260701094341.3218199-1-edumazet@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
a87a558f85
commit
5a5ebefdab
|
|
@ -2636,7 +2636,7 @@ static int macsec_update_offload(struct net_device *dev,
|
|||
vlan_drop_rx_ctag_filter_info(dev);
|
||||
vlan_drop_rx_stag_filter_info(dev);
|
||||
}
|
||||
macsec->offload = offload;
|
||||
WRITE_ONCE(macsec->offload, offload);
|
||||
/* Add VLAN filters when enabling offload. */
|
||||
if (prev_offload == MACSEC_OFFLOAD_OFF) {
|
||||
ret = vlan_get_rx_ctag_filter_info(dev);
|
||||
|
|
@ -2666,7 +2666,7 @@ static int macsec_update_offload(struct net_device *dev,
|
|||
return 0;
|
||||
|
||||
rollback_offload:
|
||||
macsec->offload = prev_offload;
|
||||
WRITE_ONCE(macsec->offload, prev_offload);
|
||||
macsec_offload(ops->mdo_del_secy, &ctx);
|
||||
|
||||
return ret;
|
||||
|
|
@ -3875,52 +3875,53 @@ static int macsec_changelink_common(struct net_device *dev,
|
|||
|
||||
if (data[IFLA_MACSEC_ENCODING_SA]) {
|
||||
struct macsec_tx_sa *tx_sa;
|
||||
u8 encoding_sa = nla_get_u8(data[IFLA_MACSEC_ENCODING_SA]);
|
||||
|
||||
tx_sc->encoding_sa = nla_get_u8(data[IFLA_MACSEC_ENCODING_SA]);
|
||||
tx_sa = rtnl_dereference(tx_sc->sa[tx_sc->encoding_sa]);
|
||||
WRITE_ONCE(tx_sc->encoding_sa, encoding_sa);
|
||||
tx_sa = rtnl_dereference(tx_sc->sa[encoding_sa]);
|
||||
|
||||
secy->operational = tx_sa && tx_sa->active;
|
||||
}
|
||||
|
||||
if (data[IFLA_MACSEC_ENCRYPT])
|
||||
tx_sc->encrypt = !!nla_get_u8(data[IFLA_MACSEC_ENCRYPT]);
|
||||
WRITE_ONCE(tx_sc->encrypt, !!nla_get_u8(data[IFLA_MACSEC_ENCRYPT]));
|
||||
|
||||
if (data[IFLA_MACSEC_PROTECT])
|
||||
secy->protect_frames = !!nla_get_u8(data[IFLA_MACSEC_PROTECT]);
|
||||
WRITE_ONCE(secy->protect_frames, !!nla_get_u8(data[IFLA_MACSEC_PROTECT]));
|
||||
|
||||
if (data[IFLA_MACSEC_INC_SCI])
|
||||
tx_sc->send_sci = !!nla_get_u8(data[IFLA_MACSEC_INC_SCI]);
|
||||
WRITE_ONCE(tx_sc->send_sci, !!nla_get_u8(data[IFLA_MACSEC_INC_SCI]));
|
||||
|
||||
if (data[IFLA_MACSEC_ES])
|
||||
tx_sc->end_station = !!nla_get_u8(data[IFLA_MACSEC_ES]);
|
||||
WRITE_ONCE(tx_sc->end_station, !!nla_get_u8(data[IFLA_MACSEC_ES]));
|
||||
|
||||
if (data[IFLA_MACSEC_SCB])
|
||||
tx_sc->scb = !!nla_get_u8(data[IFLA_MACSEC_SCB]);
|
||||
WRITE_ONCE(tx_sc->scb, !!nla_get_u8(data[IFLA_MACSEC_SCB]));
|
||||
|
||||
if (data[IFLA_MACSEC_REPLAY_PROTECT])
|
||||
secy->replay_protect = !!nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT]);
|
||||
WRITE_ONCE(secy->replay_protect, !!nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT]));
|
||||
|
||||
if (data[IFLA_MACSEC_VALIDATION])
|
||||
secy->validate_frames = nla_get_u8(data[IFLA_MACSEC_VALIDATION]);
|
||||
WRITE_ONCE(secy->validate_frames, nla_get_u8(data[IFLA_MACSEC_VALIDATION]));
|
||||
|
||||
if (data[IFLA_MACSEC_CIPHER_SUITE]) {
|
||||
switch (nla_get_u64(data[IFLA_MACSEC_CIPHER_SUITE])) {
|
||||
case MACSEC_CIPHER_ID_GCM_AES_128:
|
||||
case MACSEC_DEFAULT_CIPHER_ID:
|
||||
secy->key_len = MACSEC_GCM_AES_128_SAK_LEN;
|
||||
secy->xpn = false;
|
||||
WRITE_ONCE(secy->key_len, MACSEC_GCM_AES_128_SAK_LEN);
|
||||
WRITE_ONCE(secy->xpn, false);
|
||||
break;
|
||||
case MACSEC_CIPHER_ID_GCM_AES_256:
|
||||
secy->key_len = MACSEC_GCM_AES_256_SAK_LEN;
|
||||
secy->xpn = false;
|
||||
WRITE_ONCE(secy->key_len, MACSEC_GCM_AES_256_SAK_LEN);
|
||||
WRITE_ONCE(secy->xpn, false);
|
||||
break;
|
||||
case MACSEC_CIPHER_ID_GCM_AES_XPN_128:
|
||||
secy->key_len = MACSEC_GCM_AES_128_SAK_LEN;
|
||||
secy->xpn = true;
|
||||
WRITE_ONCE(secy->key_len, MACSEC_GCM_AES_128_SAK_LEN);
|
||||
WRITE_ONCE(secy->xpn, true);
|
||||
break;
|
||||
case MACSEC_CIPHER_ID_GCM_AES_XPN_256:
|
||||
secy->key_len = MACSEC_GCM_AES_256_SAK_LEN;
|
||||
secy->xpn = true;
|
||||
WRITE_ONCE(secy->key_len, MACSEC_GCM_AES_256_SAK_LEN);
|
||||
WRITE_ONCE(secy->xpn, true);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -3928,13 +3929,14 @@ static int macsec_changelink_common(struct net_device *dev,
|
|||
}
|
||||
|
||||
if (data[IFLA_MACSEC_WINDOW]) {
|
||||
secy->replay_window = nla_get_u32(data[IFLA_MACSEC_WINDOW]);
|
||||
u32 replay_window = nla_get_u32(data[IFLA_MACSEC_WINDOW]);
|
||||
|
||||
/* IEEE 802.1AEbw-2013 10.7.8 - maximum replay window
|
||||
* for XPN cipher suites */
|
||||
if (secy->xpn &&
|
||||
secy->replay_window > MACSEC_XPN_MAX_REPLAY_WINDOW)
|
||||
replay_window > MACSEC_XPN_MAX_REPLAY_WINDOW)
|
||||
return -EINVAL;
|
||||
WRITE_ONCE(secy->replay_window, replay_window);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -4382,21 +4384,21 @@ static size_t macsec_get_size(const struct net_device *dev)
|
|||
static int macsec_fill_info(struct sk_buff *skb,
|
||||
const struct net_device *dev)
|
||||
{
|
||||
struct macsec_tx_sc *tx_sc;
|
||||
struct macsec_dev *macsec;
|
||||
struct macsec_secy *secy;
|
||||
const struct macsec_tx_sc *tx_sc;
|
||||
const struct macsec_dev *macsec;
|
||||
const struct macsec_secy *secy;
|
||||
u64 csid;
|
||||
|
||||
macsec = macsec_priv(dev);
|
||||
secy = &macsec->secy;
|
||||
tx_sc = &secy->tx_sc;
|
||||
|
||||
switch (secy->key_len) {
|
||||
switch (READ_ONCE(secy->key_len)) {
|
||||
case MACSEC_GCM_AES_128_SAK_LEN:
|
||||
csid = secy->xpn ? MACSEC_CIPHER_ID_GCM_AES_XPN_128 : MACSEC_DEFAULT_CIPHER_ID;
|
||||
csid = READ_ONCE(secy->xpn) ? MACSEC_CIPHER_ID_GCM_AES_XPN_128 : MACSEC_DEFAULT_CIPHER_ID;
|
||||
break;
|
||||
case MACSEC_GCM_AES_256_SAK_LEN:
|
||||
csid = secy->xpn ? MACSEC_CIPHER_ID_GCM_AES_XPN_256 : MACSEC_CIPHER_ID_GCM_AES_256;
|
||||
csid = READ_ONCE(secy->xpn) ? MACSEC_CIPHER_ID_GCM_AES_XPN_256 : MACSEC_CIPHER_ID_GCM_AES_256;
|
||||
break;
|
||||
default:
|
||||
goto nla_put_failure;
|
||||
|
|
@ -4407,20 +4409,20 @@ static int macsec_fill_info(struct sk_buff *skb,
|
|||
nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) ||
|
||||
nla_put_u64_64bit(skb, IFLA_MACSEC_CIPHER_SUITE,
|
||||
csid, IFLA_MACSEC_PAD) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_INC_SCI, tx_sc->send_sci) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_ES, tx_sc->end_station) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_SCB, tx_sc->scb) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_REPLAY_PROTECT, secy->replay_protect) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_VALIDATION, secy->validate_frames) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_OFFLOAD, macsec->offload) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, READ_ONCE(tx_sc->encoding_sa)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, READ_ONCE(tx_sc->encrypt)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_PROTECT, READ_ONCE(secy->protect_frames)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_INC_SCI, READ_ONCE(tx_sc->send_sci)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_ES, READ_ONCE(tx_sc->end_station)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_SCB, READ_ONCE(tx_sc->scb)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_REPLAY_PROTECT, READ_ONCE(secy->replay_protect)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_VALIDATION, READ_ONCE(secy->validate_frames)) ||
|
||||
nla_put_u8(skb, IFLA_MACSEC_OFFLOAD, READ_ONCE(macsec->offload)) ||
|
||||
0)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (secy->replay_protect) {
|
||||
if (nla_put_u32(skb, IFLA_MACSEC_WINDOW, secy->replay_window))
|
||||
if (READ_ONCE(secy->replay_protect)) {
|
||||
if (nla_put_u32(skb, IFLA_MACSEC_WINDOW, READ_ONCE(secy->replay_window)))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user