Skip to content

Commit fdb0611

Browse files
author
Paolo Abeni
committed
Merge tag 'ipsec-next-2025-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== 1) Remove some unnecessary strscpy_pad() size arguments. From Thorsten Blum. 2) Correct use of xso.real_dev on bonding offloads. Patchset from Cosmin Ratiu. 3) Add hardware offload configuration to XFRM_MSG_MIGRATE. From Chiachang Wang. 4) Refactor migration setup during cloning. This was done after the clone was created. Now it is done in the cloning function itself. From Chiachang Wang. 5) Validate assignment of maximal possible SEQ number. Prevent from setting to the maximum sequrnce number as this would cause for traffic drop. From Leon Romanovsky. 6) Prevent configuration of interface index when offload is used. Hardware can't handle this case.i From Leon Romanovsky. 7) Always use kfree_sensitive() for SA secret zeroization. From Zilin Guan. ipsec-next-2025-05-23 * tag 'ipsec-next-2025-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next: xfrm: use kfree_sensitive() for SA secret zeroization xfrm: prevent configuration of interface index when offload is used xfrm: validate assignment of maximal possible SEQ number xfrm: Refactor migration setup during the cloning process xfrm: Migrate offload configuration bonding: Fix multiple long standing offload races bonding: Mark active offloaded xfrm_states xfrm: Add explicit dev to .xdo_dev_state_{add,delete,free} xfrm: Remove unneeded device check from validate_xmit_xfrm xfrm: Use xdo.dev instead of xdo.real_dev net/mlx5: Avoid using xso.real_dev unnecessarily xfrm: Remove unnecessary strscpy_pad() size arguments ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 34d2631 + e7a37c9 commit fdb0611

File tree

18 files changed

+277
-201
lines changed

18 files changed

+277
-201
lines changed

Documentation/networking/xfrm_device.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,13 @@ Callbacks to implement
6565
/* from include/linux/netdevice.h */
6666
struct xfrmdev_ops {
6767
/* Crypto and Packet offload callbacks */
68-
int (*xdo_dev_state_add) (struct xfrm_state *x, struct netlink_ext_ack *extack);
69-
void (*xdo_dev_state_delete) (struct xfrm_state *x);
70-
void (*xdo_dev_state_free) (struct xfrm_state *x);
68+
int (*xdo_dev_state_add)(struct net_device *dev,
69+
struct xfrm_state *x,
70+
struct netlink_ext_ack *extack);
71+
void (*xdo_dev_state_delete)(struct net_device *dev,
72+
struct xfrm_state *x);
73+
void (*xdo_dev_state_free)(struct net_device *dev,
74+
struct xfrm_state *x);
7175
bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
7276
struct xfrm_state *x);
7377
void (*xdo_dev_state_advance_esn) (struct xfrm_state *x);

drivers/net/bonding/bond_main.c

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -453,13 +453,14 @@ static struct net_device *bond_ipsec_dev(struct xfrm_state *xs)
453453

454454
/**
455455
* bond_ipsec_add_sa - program device with a security association
456+
* @bond_dev: pointer to the bond net device
456457
* @xs: pointer to transformer state struct
457458
* @extack: extack point to fill failure reason
458459
**/
459-
static int bond_ipsec_add_sa(struct xfrm_state *xs,
460+
static int bond_ipsec_add_sa(struct net_device *bond_dev,
461+
struct xfrm_state *xs,
460462
struct netlink_ext_ack *extack)
461463
{
462-
struct net_device *bond_dev = xs->xso.dev;
463464
struct net_device *real_dev;
464465
netdevice_tracker tracker;
465466
struct bond_ipsec *ipsec;
@@ -495,9 +496,9 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs,
495496
goto out;
496497
}
497498

498-
xs->xso.real_dev = real_dev;
499-
err = real_dev->xfrmdev_ops->xdo_dev_state_add(xs, extack);
499+
err = real_dev->xfrmdev_ops->xdo_dev_state_add(real_dev, xs, extack);
500500
if (!err) {
501+
xs->xso.real_dev = real_dev;
501502
ipsec->xs = xs;
502503
INIT_LIST_HEAD(&ipsec->list);
503504
mutex_lock(&bond->ipsec_lock);
@@ -539,66 +540,53 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
539540
if (ipsec->xs->xso.real_dev == real_dev)
540541
continue;
541542

542-
ipsec->xs->xso.real_dev = real_dev;
543-
if (real_dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) {
543+
if (real_dev->xfrmdev_ops->xdo_dev_state_add(real_dev,
544+
ipsec->xs, NULL)) {
544545
slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__);
545-
ipsec->xs->xso.real_dev = NULL;
546+
continue;
546547
}
548+
549+
spin_lock_bh(&ipsec->xs->lock);
550+
/* xs might have been killed by the user during the migration
551+
* to the new dev, but bond_ipsec_del_sa() should have done
552+
* nothing, as xso.real_dev is NULL.
553+
* Delete it from the device we just added it to. The pending
554+
* bond_ipsec_free_sa() call will do the rest of the cleanup.
555+
*/
556+
if (ipsec->xs->km.state == XFRM_STATE_DEAD &&
557+
real_dev->xfrmdev_ops->xdo_dev_state_delete)
558+
real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
559+
ipsec->xs);
560+
ipsec->xs->xso.real_dev = real_dev;
561+
spin_unlock_bh(&ipsec->xs->lock);
547562
}
548563
out:
549564
mutex_unlock(&bond->ipsec_lock);
550565
}
551566

552567
/**
553568
* bond_ipsec_del_sa - clear out this specific SA
569+
* @bond_dev: pointer to the bond net device
554570
* @xs: pointer to transformer state struct
555571
**/
556-
static void bond_ipsec_del_sa(struct xfrm_state *xs)
572+
static void bond_ipsec_del_sa(struct net_device *bond_dev,
573+
struct xfrm_state *xs)
557574
{
558-
struct net_device *bond_dev = xs->xso.dev;
559575
struct net_device *real_dev;
560-
netdevice_tracker tracker;
561-
struct bond_ipsec *ipsec;
562-
struct bonding *bond;
563-
struct slave *slave;
564576

565-
if (!bond_dev)
577+
if (!bond_dev || !xs->xso.real_dev)
566578
return;
567579

568-
rcu_read_lock();
569-
bond = netdev_priv(bond_dev);
570-
slave = rcu_dereference(bond->curr_active_slave);
571-
real_dev = slave ? slave->dev : NULL;
572-
netdev_hold(real_dev, &tracker, GFP_ATOMIC);
573-
rcu_read_unlock();
574-
575-
if (!slave)
576-
goto out;
577-
578-
if (!xs->xso.real_dev)
579-
goto out;
580-
581-
WARN_ON(xs->xso.real_dev != real_dev);
580+
real_dev = xs->xso.real_dev;
582581

583582
if (!real_dev->xfrmdev_ops ||
584583
!real_dev->xfrmdev_ops->xdo_dev_state_delete ||
585584
netif_is_bond_master(real_dev)) {
586585
slave_warn(bond_dev, real_dev, "%s: no slave xdo_dev_state_delete\n", __func__);
587-
goto out;
586+
return;
588587
}
589588

590-
real_dev->xfrmdev_ops->xdo_dev_state_delete(xs);
591-
out:
592-
netdev_put(real_dev, &tracker);
593-
mutex_lock(&bond->ipsec_lock);
594-
list_for_each_entry(ipsec, &bond->ipsec_list, list) {
595-
if (ipsec->xs == xs) {
596-
list_del(&ipsec->list);
597-
kfree(ipsec);
598-
break;
599-
}
600-
}
601-
mutex_unlock(&bond->ipsec_lock);
589+
real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev, xs);
602590
}
603591

604592
static void bond_ipsec_del_sa_all(struct bonding *bond)
@@ -624,46 +612,55 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
624612
slave_warn(bond_dev, real_dev,
625613
"%s: no slave xdo_dev_state_delete\n",
626614
__func__);
627-
} else {
628-
real_dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
629-
if (real_dev->xfrmdev_ops->xdo_dev_state_free)
630-
real_dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs);
615+
continue;
631616
}
617+
618+
spin_lock_bh(&ipsec->xs->lock);
619+
ipsec->xs->xso.real_dev = NULL;
620+
/* Don't double delete states killed by the user. */
621+
if (ipsec->xs->km.state != XFRM_STATE_DEAD)
622+
real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
623+
ipsec->xs);
624+
spin_unlock_bh(&ipsec->xs->lock);
625+
626+
if (real_dev->xfrmdev_ops->xdo_dev_state_free)
627+
real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev,
628+
ipsec->xs);
632629
}
633630
mutex_unlock(&bond->ipsec_lock);
634631
}
635632

636-
static void bond_ipsec_free_sa(struct xfrm_state *xs)
633+
static void bond_ipsec_free_sa(struct net_device *bond_dev,
634+
struct xfrm_state *xs)
637635
{
638-
struct net_device *bond_dev = xs->xso.dev;
639636
struct net_device *real_dev;
640-
netdevice_tracker tracker;
637+
struct bond_ipsec *ipsec;
641638
struct bonding *bond;
642-
struct slave *slave;
643639

644640
if (!bond_dev)
645641
return;
646642

647-
rcu_read_lock();
648643
bond = netdev_priv(bond_dev);
649-
slave = rcu_dereference(bond->curr_active_slave);
650-
real_dev = slave ? slave->dev : NULL;
651-
netdev_hold(real_dev, &tracker, GFP_ATOMIC);
652-
rcu_read_unlock();
653-
654-
if (!slave)
655-
goto out;
656644

645+
mutex_lock(&bond->ipsec_lock);
657646
if (!xs->xso.real_dev)
658647
goto out;
659648

660-
WARN_ON(xs->xso.real_dev != real_dev);
649+
real_dev = xs->xso.real_dev;
661650

662-
if (real_dev && real_dev->xfrmdev_ops &&
651+
xs->xso.real_dev = NULL;
652+
if (real_dev->xfrmdev_ops &&
663653
real_dev->xfrmdev_ops->xdo_dev_state_free)
664-
real_dev->xfrmdev_ops->xdo_dev_state_free(xs);
654+
real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev, xs);
665655
out:
666-
netdev_put(real_dev, &tracker);
656+
list_for_each_entry(ipsec, &bond->ipsec_list, list) {
657+
if (ipsec->xs == xs) {
658+
list_del(&ipsec->list);
659+
kfree(ipsec);
660+
break;
661+
}
662+
}
663+
mutex_unlock(&bond->ipsec_lock);
667664
}
668665

669666
/**

drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6480,10 +6480,11 @@ static const struct tlsdev_ops cxgb4_ktls_ops = {
64806480

64816481
#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
64826482

6483-
static int cxgb4_xfrm_add_state(struct xfrm_state *x,
6483+
static int cxgb4_xfrm_add_state(struct net_device *dev,
6484+
struct xfrm_state *x,
64846485
struct netlink_ext_ack *extack)
64856486
{
6486-
struct adapter *adap = netdev2adap(x->xso.dev);
6487+
struct adapter *adap = netdev2adap(dev);
64876488
int ret;
64886489

64896490
if (!mutex_trylock(&uld_mutex)) {
@@ -6494,17 +6495,18 @@ static int cxgb4_xfrm_add_state(struct xfrm_state *x,
64946495
if (ret)
64956496
goto out_unlock;
64966497

6497-
ret = adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_add(x, extack);
6498+
ret = adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_add(dev, x,
6499+
extack);
64986500

64996501
out_unlock:
65006502
mutex_unlock(&uld_mutex);
65016503

65026504
return ret;
65036505
}
65046506

6505-
static void cxgb4_xfrm_del_state(struct xfrm_state *x)
6507+
static void cxgb4_xfrm_del_state(struct net_device *dev, struct xfrm_state *x)
65066508
{
6507-
struct adapter *adap = netdev2adap(x->xso.dev);
6509+
struct adapter *adap = netdev2adap(dev);
65086510

65096511
if (!mutex_trylock(&uld_mutex)) {
65106512
dev_dbg(adap->pdev_dev,
@@ -6514,15 +6516,15 @@ static void cxgb4_xfrm_del_state(struct xfrm_state *x)
65146516
if (chcr_offload_state(adap, CXGB4_XFRMDEV_OPS))
65156517
goto out_unlock;
65166518

6517-
adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_delete(x);
6519+
adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_delete(dev, x);
65186520

65196521
out_unlock:
65206522
mutex_unlock(&uld_mutex);
65216523
}
65226524

6523-
static void cxgb4_xfrm_free_state(struct xfrm_state *x)
6525+
static void cxgb4_xfrm_free_state(struct net_device *dev, struct xfrm_state *x)
65246526
{
6525-
struct adapter *adap = netdev2adap(x->xso.dev);
6527+
struct adapter *adap = netdev2adap(dev);
65266528

65276529
if (!mutex_trylock(&uld_mutex)) {
65286530
dev_dbg(adap->pdev_dev,
@@ -6532,7 +6534,7 @@ static void cxgb4_xfrm_free_state(struct xfrm_state *x)
65326534
if (chcr_offload_state(adap, CXGB4_XFRMDEV_OPS))
65336535
goto out_unlock;
65346536

6535-
adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_free(x);
6537+
adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_free(dev, x);
65366538

65376539
out_unlock:
65386540
mutex_unlock(&uld_mutex);

drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ static int ch_ipsec_uld_state_change(void *handle, enum cxgb4_state new_state);
7575
static int ch_ipsec_xmit(struct sk_buff *skb, struct net_device *dev);
7676
static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop);
7777
static void ch_ipsec_advance_esn_state(struct xfrm_state *x);
78-
static void ch_ipsec_xfrm_free_state(struct xfrm_state *x);
79-
static void ch_ipsec_xfrm_del_state(struct xfrm_state *x);
80-
static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
78+
static void ch_ipsec_xfrm_free_state(struct net_device *dev,
79+
struct xfrm_state *x);
80+
static void ch_ipsec_xfrm_del_state(struct net_device *dev,
81+
struct xfrm_state *x);
82+
static int ch_ipsec_xfrm_add_state(struct net_device *dev,
83+
struct xfrm_state *x,
8184
struct netlink_ext_ack *extack);
8285

8386
static const struct xfrmdev_ops ch_ipsec_xfrmdev_ops = {
@@ -223,7 +226,8 @@ static int ch_ipsec_setkey(struct xfrm_state *x,
223226
* returns 0 on success, negative error if failed to send message to FPGA
224227
* positive error if FPGA returned a bad response
225228
*/
226-
static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
229+
static int ch_ipsec_xfrm_add_state(struct net_device *dev,
230+
struct xfrm_state *x,
227231
struct netlink_ext_ack *extack)
228232
{
229233
struct ipsec_sa_entry *sa_entry;
@@ -302,14 +306,16 @@ static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
302306
return res;
303307
}
304308

305-
static void ch_ipsec_xfrm_del_state(struct xfrm_state *x)
309+
static void ch_ipsec_xfrm_del_state(struct net_device *dev,
310+
struct xfrm_state *x)
306311
{
307312
/* do nothing */
308313
if (!x->xso.offload_handle)
309314
return;
310315
}
311316

312-
static void ch_ipsec_xfrm_free_state(struct xfrm_state *x)
317+
static void ch_ipsec_xfrm_free_state(struct net_device *dev,
318+
struct xfrm_state *x)
313319
{
314320
struct ipsec_sa_entry *sa_entry;
315321

0 commit comments

Comments
 (0)