@@ -427,6 +427,8 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs,
427427 struct netlink_ext_ack * extack )
428428{
429429 struct net_device * bond_dev = xs -> xso .dev ;
430+ struct net_device * real_dev ;
431+ netdevice_tracker tracker ;
430432 struct bond_ipsec * ipsec ;
431433 struct bonding * bond ;
432434 struct slave * slave ;
@@ -438,74 +440,80 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs,
438440 rcu_read_lock ();
439441 bond = netdev_priv (bond_dev );
440442 slave = rcu_dereference (bond -> curr_active_slave );
441- if (!slave ) {
442- rcu_read_unlock ();
443- return - ENODEV ;
443+ real_dev = slave ? slave -> dev : NULL ;
444+ netdev_hold (real_dev , & tracker , GFP_ATOMIC );
445+ rcu_read_unlock ();
446+ if (!real_dev ) {
447+ err = - ENODEV ;
448+ goto out ;
444449 }
445450
446- if (!slave -> dev -> xfrmdev_ops ||
447- !slave -> dev -> xfrmdev_ops -> xdo_dev_state_add ||
448- netif_is_bond_master (slave -> dev )) {
451+ if (!real_dev -> xfrmdev_ops ||
452+ !real_dev -> xfrmdev_ops -> xdo_dev_state_add ||
453+ netif_is_bond_master (real_dev )) {
449454 NL_SET_ERR_MSG_MOD (extack , "Slave does not support ipsec offload" );
450- rcu_read_unlock () ;
451- return - EINVAL ;
455+ err = - EINVAL ;
456+ goto out ;
452457 }
453458
454- ipsec = kmalloc (sizeof (* ipsec ), GFP_ATOMIC );
459+ ipsec = kmalloc (sizeof (* ipsec ), GFP_KERNEL );
455460 if (!ipsec ) {
456- rcu_read_unlock () ;
457- return - ENOMEM ;
461+ err = - ENOMEM ;
462+ goto out ;
458463 }
459- xs -> xso .real_dev = slave -> dev ;
460464
461- err = slave -> dev -> xfrmdev_ops -> xdo_dev_state_add (xs , extack );
465+ xs -> xso .real_dev = real_dev ;
466+ err = real_dev -> xfrmdev_ops -> xdo_dev_state_add (xs , extack );
462467 if (!err ) {
463468 ipsec -> xs = xs ;
464469 INIT_LIST_HEAD (& ipsec -> list );
465- spin_lock_bh (& bond -> ipsec_lock );
470+ mutex_lock (& bond -> ipsec_lock );
466471 list_add (& ipsec -> list , & bond -> ipsec_list );
467- spin_unlock_bh (& bond -> ipsec_lock );
472+ mutex_unlock (& bond -> ipsec_lock );
468473 } else {
469474 kfree (ipsec );
470475 }
471- rcu_read_unlock ();
476+ out :
477+ netdev_put (real_dev , & tracker );
472478 return err ;
473479}
474480
475481static void bond_ipsec_add_sa_all (struct bonding * bond )
476482{
477483 struct net_device * bond_dev = bond -> dev ;
484+ struct net_device * real_dev ;
478485 struct bond_ipsec * ipsec ;
479486 struct slave * slave ;
480487
481- rcu_read_lock ( );
482- slave = rcu_dereference ( bond -> curr_active_slave ) ;
483- if (!slave )
484- goto out ;
488+ slave = rtnl_dereference ( bond -> curr_active_slave );
489+ real_dev = slave ? slave -> dev : NULL ;
490+ if (!real_dev )
491+ return ;
485492
486- if (! slave -> dev -> xfrmdev_ops ||
487- ! slave -> dev -> xfrmdev_ops -> xdo_dev_state_add ||
488- netif_is_bond_master ( slave -> dev )) {
489- spin_lock_bh ( & bond -> ipsec_lock );
493+ mutex_lock ( & bond -> ipsec_lock );
494+ if (! real_dev -> xfrmdev_ops ||
495+ ! real_dev -> xfrmdev_ops -> xdo_dev_state_add ||
496+ netif_is_bond_master ( real_dev )) {
490497 if (!list_empty (& bond -> ipsec_list ))
491- slave_warn (bond_dev , slave -> dev ,
498+ slave_warn (bond_dev , real_dev ,
492499 "%s: no slave xdo_dev_state_add\n" ,
493500 __func__ );
494- spin_unlock_bh (& bond -> ipsec_lock );
495501 goto out ;
496502 }
497503
498- spin_lock_bh (& bond -> ipsec_lock );
499504 list_for_each_entry (ipsec , & bond -> ipsec_list , list ) {
500- ipsec -> xs -> xso .real_dev = slave -> dev ;
501- if (slave -> dev -> xfrmdev_ops -> xdo_dev_state_add (ipsec -> xs , NULL )) {
502- slave_warn (bond_dev , slave -> dev , "%s: failed to add SA\n" , __func__ );
505+ /* If new state is added before ipsec_lock acquired */
506+ if (ipsec -> xs -> xso .real_dev == real_dev )
507+ continue ;
508+
509+ ipsec -> xs -> xso .real_dev = real_dev ;
510+ if (real_dev -> xfrmdev_ops -> xdo_dev_state_add (ipsec -> xs , NULL )) {
511+ slave_warn (bond_dev , real_dev , "%s: failed to add SA\n" , __func__ );
503512 ipsec -> xs -> xso .real_dev = NULL ;
504513 }
505514 }
506- spin_unlock_bh (& bond -> ipsec_lock );
507515out :
508- rcu_read_unlock ( );
516+ mutex_unlock ( & bond -> ipsec_lock );
509517}
510518
511519/**
@@ -515,6 +523,8 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
515523static void bond_ipsec_del_sa (struct xfrm_state * xs )
516524{
517525 struct net_device * bond_dev = xs -> xso .dev ;
526+ struct net_device * real_dev ;
527+ netdevice_tracker tracker ;
518528 struct bond_ipsec * ipsec ;
519529 struct bonding * bond ;
520530 struct slave * slave ;
@@ -525,66 +535,102 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs)
525535 rcu_read_lock ();
526536 bond = netdev_priv (bond_dev );
527537 slave = rcu_dereference (bond -> curr_active_slave );
538+ real_dev = slave ? slave -> dev : NULL ;
539+ netdev_hold (real_dev , & tracker , GFP_ATOMIC );
540+ rcu_read_unlock ();
528541
529542 if (!slave )
530543 goto out ;
531544
532545 if (!xs -> xso .real_dev )
533546 goto out ;
534547
535- WARN_ON (xs -> xso .real_dev != slave -> dev );
548+ WARN_ON (xs -> xso .real_dev != real_dev );
536549
537- if (!slave -> dev -> xfrmdev_ops ||
538- !slave -> dev -> xfrmdev_ops -> xdo_dev_state_delete ||
539- netif_is_bond_master (slave -> dev )) {
540- slave_warn (bond_dev , slave -> dev , "%s: no slave xdo_dev_state_delete\n" , __func__ );
550+ if (!real_dev -> xfrmdev_ops ||
551+ !real_dev -> xfrmdev_ops -> xdo_dev_state_delete ||
552+ netif_is_bond_master (real_dev )) {
553+ slave_warn (bond_dev , real_dev , "%s: no slave xdo_dev_state_delete\n" , __func__ );
541554 goto out ;
542555 }
543556
544- slave -> dev -> xfrmdev_ops -> xdo_dev_state_delete (xs );
557+ real_dev -> xfrmdev_ops -> xdo_dev_state_delete (xs );
545558out :
546- spin_lock_bh (& bond -> ipsec_lock );
559+ netdev_put (real_dev , & tracker );
560+ mutex_lock (& bond -> ipsec_lock );
547561 list_for_each_entry (ipsec , & bond -> ipsec_list , list ) {
548562 if (ipsec -> xs == xs ) {
549563 list_del (& ipsec -> list );
550564 kfree (ipsec );
551565 break ;
552566 }
553567 }
554- spin_unlock_bh (& bond -> ipsec_lock );
555- rcu_read_unlock ();
568+ mutex_unlock (& bond -> ipsec_lock );
556569}
557570
558571static void bond_ipsec_del_sa_all (struct bonding * bond )
559572{
560573 struct net_device * bond_dev = bond -> dev ;
574+ struct net_device * real_dev ;
561575 struct bond_ipsec * ipsec ;
562576 struct slave * slave ;
563577
564- rcu_read_lock ();
565- slave = rcu_dereference (bond -> curr_active_slave );
566- if (!slave ) {
567- rcu_read_unlock ();
578+ slave = rtnl_dereference (bond -> curr_active_slave );
579+ real_dev = slave ? slave -> dev : NULL ;
580+ if (!real_dev )
568581 return ;
569- }
570582
571- spin_lock_bh (& bond -> ipsec_lock );
583+ mutex_lock (& bond -> ipsec_lock );
572584 list_for_each_entry (ipsec , & bond -> ipsec_list , list ) {
573585 if (!ipsec -> xs -> xso .real_dev )
574586 continue ;
575587
576- if (!slave -> dev -> xfrmdev_ops ||
577- !slave -> dev -> xfrmdev_ops -> xdo_dev_state_delete ||
578- netif_is_bond_master (slave -> dev )) {
579- slave_warn (bond_dev , slave -> dev ,
588+ if (!real_dev -> xfrmdev_ops ||
589+ !real_dev -> xfrmdev_ops -> xdo_dev_state_delete ||
590+ netif_is_bond_master (real_dev )) {
591+ slave_warn (bond_dev , real_dev ,
580592 "%s: no slave xdo_dev_state_delete\n" ,
581593 __func__ );
582594 } else {
583- slave -> dev -> xfrmdev_ops -> xdo_dev_state_delete (ipsec -> xs );
595+ real_dev -> xfrmdev_ops -> xdo_dev_state_delete (ipsec -> xs );
596+ if (real_dev -> xfrmdev_ops -> xdo_dev_state_free )
597+ real_dev -> xfrmdev_ops -> xdo_dev_state_free (ipsec -> xs );
584598 }
585599 }
586- spin_unlock_bh (& bond -> ipsec_lock );
600+ mutex_unlock (& bond -> ipsec_lock );
601+ }
602+
603+ static void bond_ipsec_free_sa (struct xfrm_state * xs )
604+ {
605+ struct net_device * bond_dev = xs -> xso .dev ;
606+ struct net_device * real_dev ;
607+ netdevice_tracker tracker ;
608+ struct bonding * bond ;
609+ struct slave * slave ;
610+
611+ if (!bond_dev )
612+ return ;
613+
614+ rcu_read_lock ();
615+ bond = netdev_priv (bond_dev );
616+ slave = rcu_dereference (bond -> curr_active_slave );
617+ real_dev = slave ? slave -> dev : NULL ;
618+ netdev_hold (real_dev , & tracker , GFP_ATOMIC );
587619 rcu_read_unlock ();
620+
621+ if (!slave )
622+ goto out ;
623+
624+ if (!xs -> xso .real_dev )
625+ goto out ;
626+
627+ WARN_ON (xs -> xso .real_dev != real_dev );
628+
629+ if (real_dev && real_dev -> xfrmdev_ops &&
630+ real_dev -> xfrmdev_ops -> xdo_dev_state_free )
631+ real_dev -> xfrmdev_ops -> xdo_dev_state_free (xs );
632+ out :
633+ netdev_put (real_dev , & tracker );
588634}
589635
590636/**
@@ -627,6 +673,7 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
627673static const struct xfrmdev_ops bond_xfrmdev_ops = {
628674 .xdo_dev_state_add = bond_ipsec_add_sa ,
629675 .xdo_dev_state_delete = bond_ipsec_del_sa ,
676+ .xdo_dev_state_free = bond_ipsec_free_sa ,
630677 .xdo_dev_offload_ok = bond_ipsec_offload_ok ,
631678};
632679#endif /* CONFIG_XFRM_OFFLOAD */
@@ -5877,7 +5924,7 @@ void bond_setup(struct net_device *bond_dev)
58775924 /* set up xfrm device ops (only supported in active-backup right now) */
58785925 bond_dev -> xfrmdev_ops = & bond_xfrmdev_ops ;
58795926 INIT_LIST_HEAD (& bond -> ipsec_list );
5880- spin_lock_init (& bond -> ipsec_lock );
5927+ mutex_init (& bond -> ipsec_lock );
58815928#endif /* CONFIG_XFRM_OFFLOAD */
58825929
58835930 /* don't acquire bond device's netif_tx_lock when transmitting */
@@ -5926,6 +5973,10 @@ static void bond_uninit(struct net_device *bond_dev)
59265973 __bond_release_one (bond_dev , slave -> dev , true, true);
59275974 netdev_info (bond_dev , "Released all slaves\n" );
59285975
5976+ #ifdef CONFIG_XFRM_OFFLOAD
5977+ mutex_destroy (& bond -> ipsec_lock );
5978+ #endif /* CONFIG_XFRM_OFFLOAD */
5979+
59295980 bond_set_slave_arr (bond , NULL , NULL );
59305981
59315982 list_del_rcu (& bond -> bond_list );
0 commit comments