Subject: Re: [PATCHv2 net-next 1/3] bonding: add common function to check ipsec device

From: kernel test robot <[email-masked]>
Date: Tue, 20 Aug 2024 03:24:25 +0800

Hi Hangbin,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Hangbin-Liu/bonding-add-common-function-to-check-ipsec-device/20240819-195504
base:   net-next/main
patch link:    https://lore.kernel.org/r/20240819075334.236334-2-liuhangbin%40gmail.com
patch subject: [PATCHv2 net-next 1/3] bonding: add common function to check ipsec device
config: x86_64-buildonly-randconfig-001-20240820 (https://download.01.org/0day-ci/archive/20240820/[email-masked]/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240820/[email-masked]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email-masked]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email-masked]/

All errors (new ones prefixed by >>):

>> drivers/net/bonding/bond_main.c:434:10: error: returning 'void *' from a function with incompatible result type 'struct net_device'
     434 |                 return NULL;
         |                        ^~~~
   include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
       8 | #define NULL ((void *)0)
         |              ^~~~~~~~~~~
   drivers/net/bonding/bond_main.c:442:10: error: returning 'void *' from a function with incompatible result type 'struct net_device'
     442 |                 return NULL;
         |                        ^~~~
   include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
       8 | #define NULL ((void *)0)
         |              ^~~~~~~~~~~
>> drivers/net/bonding/bond_main.c:446:9: error: returning 'struct net_device *' from a function with incompatible result type 'struct net_device'; dereference with *
     446 |         return real_dev;
         |                ^~~~~~~~
         |                *
>> drivers/net/bonding/bond_main.c:630:11: error: assigning to 'struct net_device *' from incompatible type 'struct net_device'
     630 |         real_dev = bond_ipsec_dev(xs);
         |                  ^ ~~~~~~~~~~~~~~~~~~
   4 errors generated.

vim +434 drivers/net/bonding/bond_main.c

   419	
   420	#ifdef CONFIG_XFRM_OFFLOAD
   421	/**
   422	 * bond_ipsec_dev - return the device for ipsec offload, or NULL if not exist
   423	 *                  caller must hold rcu_read_lock.
   424	 * @xs: pointer to transformer state struct
   425	 **/
   426	static struct net_device bond_ipsec_dev(struct xfrm_state *xs)
   427	{
   428		struct net_device *bond_dev = xs->xso.dev;
   429		struct net_device *real_dev;
   430		struct bonding *bond;
   431		struct slave *slave;
   432	
   433		if (!bond_dev)
 > 434			return NULL;
   435	
   436		bond = netdev_priv(bond_dev);
   437		slave = rcu_dereference(bond->curr_active_slave);
   438		real_dev = slave ? slave->dev : NULL;
   439	
   440		if ((BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) ||
   441		    !slave || !real_dev || !xs->xso.real_dev)
   442			return NULL;
   443	
   444		WARN_ON(xs->xso.real_dev != slave->dev);
   445	
 > 446		return real_dev;
   447	}
   448	
   449	/**
   450	 * bond_ipsec_add_sa - program device with a security association
   451	 * @xs: pointer to transformer state struct
   452	 * @extack: extack point to fill failure reason
   453	 **/
   454	static int bond_ipsec_add_sa(struct xfrm_state *xs,
   455				     struct netlink_ext_ack *extack)
   456	{
   457		struct net_device *bond_dev = xs->xso.dev;
   458		struct bond_ipsec *ipsec;
   459		struct bonding *bond;
   460		struct slave *slave;
   461		int err;
   462	
   463		if (!bond_dev)
   464			return -EINVAL;
   465	
   466		rcu_read_lock();
   467		bond = netdev_priv(bond_dev);
   468		slave = rcu_dereference(bond->curr_active_slave);
   469		if (!slave) {
   470			rcu_read_unlock();
   471			return -ENODEV;
   472		}
   473	
   474		if (!slave->dev->xfrmdev_ops ||
   475		    !slave->dev->xfrmdev_ops->xdo_dev_state_add ||
   476		    netif_is_bond_master(slave->dev)) {
   477			NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload");
   478			rcu_read_unlock();
   479			return -EINVAL;
   480		}
   481	
   482		ipsec = kmalloc(sizeof(*ipsec), GFP_ATOMIC);
   483		if (!ipsec) {
   484			rcu_read_unlock();
   485			return -ENOMEM;
   486		}
   487		xs->xso.real_dev = slave->dev;
   488	
   489		err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs, extack);
   490		if (!err) {
   491			ipsec->xs = xs;
   492			INIT_LIST_HEAD(&ipsec->list);
   493			spin_lock_bh(&bond->ipsec_lock);
   494			list_add(&ipsec->list, &bond->ipsec_list);
   495			spin_unlock_bh(&bond->ipsec_lock);
   496		} else {
   497			kfree(ipsec);
   498		}
   499		rcu_read_unlock();
   500		return err;
   501	}
   502	
   503	static void bond_ipsec_add_sa_all(struct bonding *bond)
   504	{
   505		struct net_device *bond_dev = bond->dev;
   506		struct bond_ipsec *ipsec;
   507		struct slave *slave;
   508	
   509		rcu_read_lock();
   510		slave = rcu_dereference(bond->curr_active_slave);
   511		if (!slave)
   512			goto out;
   513	
   514		if (!slave->dev->xfrmdev_ops ||
   515		    !slave->dev->xfrmdev_ops->xdo_dev_state_add ||
   516		    netif_is_bond_master(slave->dev)) {
   517			spin_lock_bh(&bond->ipsec_lock);
   518			if (!list_empty(&bond->ipsec_list))
   519				slave_warn(bond_dev, slave->dev,
   520					   "%s: no slave xdo_dev_state_add\n",
   521					   __func__);
   522			spin_unlock_bh(&bond->ipsec_lock);
   523			goto out;
   524		}
   525	
   526		spin_lock_bh(&bond->ipsec_lock);
   527		list_for_each_entry(ipsec, &bond->ipsec_list, list) {
   528			ipsec->xs->xso.real_dev = slave->dev;
   529			if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) {
   530				slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__);
   531				ipsec->xs->xso.real_dev = NULL;
   532			}
   533		}
   534		spin_unlock_bh(&bond->ipsec_lock);
   535	out:
   536		rcu_read_unlock();
   537	}
   538	
   539	/**
   540	 * bond_ipsec_del_sa - clear out this specific SA
   541	 * @xs: pointer to transformer state struct
   542	 **/
   543	static void bond_ipsec_del_sa(struct xfrm_state *xs)
   544	{
   545		struct net_device *bond_dev = xs->xso.dev;
   546		struct bond_ipsec *ipsec;
   547		struct bonding *bond;
   548		struct slave *slave;
   549	
   550		if (!bond_dev)
   551			return;
   552	
   553		rcu_read_lock();
   554		bond = netdev_priv(bond_dev);
   555		slave = rcu_dereference(bond->curr_active_slave);
   556	
   557		if (!slave)
   558			goto out;
   559	
   560		if (!xs->xso.real_dev)
   561			goto out;
   562	
   563		WARN_ON(xs->xso.real_dev != slave->dev);
   564	
   565		if (!slave->dev->xfrmdev_ops ||
   566		    !slave->dev->xfrmdev_ops->xdo_dev_state_delete ||
   567		    netif_is_bond_master(slave->dev)) {
   568			slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
   569			goto out;
   570		}
   571	
   572		slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
   573	out:
   574		spin_lock_bh(&bond->ipsec_lock);
   575		list_for_each_entry(ipsec, &bond->ipsec_list, list) {
   576			if (ipsec->xs == xs) {
   577				list_del(&ipsec->list);
   578				kfree(ipsec);
   579				break;
   580			}
   581		}
   582		spin_unlock_bh(&bond->ipsec_lock);
   583		rcu_read_unlock();
   584	}
   585	
   586	static void bond_ipsec_del_sa_all(struct bonding *bond)
   587	{
   588		struct net_device *bond_dev = bond->dev;
   589		struct bond_ipsec *ipsec;
   590		struct slave *slave;
   591	
   592		rcu_read_lock();
   593		slave = rcu_dereference(bond->curr_active_slave);
   594		if (!slave) {
   595			rcu_read_unlock();
   596			return;
   597		}
   598	
   599		spin_lock_bh(&bond->ipsec_lock);
   600		list_for_each_entry(ipsec, &bond->ipsec_list, list) {
   601			if (!ipsec->xs->xso.real_dev)
   602				continue;
   603	
   604			if (!slave->dev->xfrmdev_ops ||
   605			    !slave->dev->xfrmdev_ops->xdo_dev_state_delete ||
   606			    netif_is_bond_master(slave->dev)) {
   607				slave_warn(bond_dev, slave->dev,
   608					   "%s: no slave xdo_dev_state_delete\n",
   609					   __func__);
   610			} else {
   611				slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
   612			}
   613			ipsec->xs->xso.real_dev = NULL;
   614		}
   615		spin_unlock_bh(&bond->ipsec_lock);
   616		rcu_read_unlock();
   617	}
   618	
   619	/**
   620	 * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
   621	 * @skb: current data packet
   622	 * @xs: pointer to transformer state struct
   623	 **/
   624	static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
   625	{
   626		struct net_device *real_dev;
   627		int err;
   628	
   629		rcu_read_lock();
 > 630		real_dev = bond_ipsec_dev(xs);
   631		if (!real_dev) {
   632			err = false;
   633			goto out;
   634		}
   635	
   636		if (!real_dev->xfrmdev_ops ||
   637		    !real_dev->xfrmdev_ops->xdo_dev_offload_ok ||
   638		    netif_is_bond_master(real_dev)) {
   639			err = false;
   640			goto out;
   641		}
   642	
   643		err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
   644	out:
   645		rcu_read_unlock();
   646		return err;
   647	}
   648	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki