@@ -3434,6 +3434,252 @@ void dev_set_rx_mode(struct net_device *dev)
34343434 netif_addr_unlock_bh (dev );
34353435}
34363436
3437+ /* hw addresses list handling functions */
3438+
3439+ static int __hw_addr_add (struct list_head * list , unsigned char * addr ,
3440+ int addr_len , unsigned char addr_type )
3441+ {
3442+ struct netdev_hw_addr * ha ;
3443+ int alloc_size ;
3444+
3445+ if (addr_len > MAX_ADDR_LEN )
3446+ return - EINVAL ;
3447+
3448+ alloc_size = sizeof (* ha );
3449+ if (alloc_size < L1_CACHE_BYTES )
3450+ alloc_size = L1_CACHE_BYTES ;
3451+ ha = kmalloc (alloc_size , GFP_ATOMIC );
3452+ if (!ha )
3453+ return - ENOMEM ;
3454+ memcpy (ha -> addr , addr , addr_len );
3455+ ha -> type = addr_type ;
3456+ list_add_tail_rcu (& ha -> list , list );
3457+ return 0 ;
3458+ }
3459+
3460+ static void ha_rcu_free (struct rcu_head * head )
3461+ {
3462+ struct netdev_hw_addr * ha ;
3463+
3464+ ha = container_of (head , struct netdev_hw_addr , rcu_head );
3465+ kfree (ha );
3466+ }
3467+
3468+ static int __hw_addr_del_ii (struct list_head * list , unsigned char * addr ,
3469+ int addr_len , unsigned char addr_type ,
3470+ int ignore_index )
3471+ {
3472+ struct netdev_hw_addr * ha ;
3473+ int i = 0 ;
3474+
3475+ list_for_each_entry (ha , list , list ) {
3476+ if (i ++ != ignore_index &&
3477+ !memcmp (ha -> addr , addr , addr_len ) &&
3478+ (ha -> type == addr_type || !addr_type )) {
3479+ list_del_rcu (& ha -> list );
3480+ call_rcu (& ha -> rcu_head , ha_rcu_free );
3481+ return 0 ;
3482+ }
3483+ }
3484+ return - ENOENT ;
3485+ }
3486+
3487+ static int __hw_addr_add_multiple_ii (struct list_head * to_list ,
3488+ struct list_head * from_list ,
3489+ int addr_len , unsigned char addr_type ,
3490+ int ignore_index )
3491+ {
3492+ int err ;
3493+ struct netdev_hw_addr * ha , * ha2 ;
3494+ unsigned char type ;
3495+
3496+ list_for_each_entry (ha , from_list , list ) {
3497+ type = addr_type ? addr_type : ha -> type ;
3498+ err = __hw_addr_add (to_list , ha -> addr , addr_len , type );
3499+ if (err )
3500+ goto unroll ;
3501+ }
3502+ return 0 ;
3503+
3504+ unroll :
3505+ list_for_each_entry (ha2 , from_list , list ) {
3506+ if (ha2 == ha )
3507+ break ;
3508+ type = addr_type ? addr_type : ha2 -> type ;
3509+ __hw_addr_del_ii (to_list , ha2 -> addr , addr_len , type ,
3510+ ignore_index );
3511+ }
3512+ return err ;
3513+ }
3514+
3515+ static void __hw_addr_del_multiple_ii (struct list_head * to_list ,
3516+ struct list_head * from_list ,
3517+ int addr_len , unsigned char addr_type ,
3518+ int ignore_index )
3519+ {
3520+ struct netdev_hw_addr * ha ;
3521+ unsigned char type ;
3522+
3523+ list_for_each_entry (ha , from_list , list ) {
3524+ type = addr_type ? addr_type : ha -> type ;
3525+ __hw_addr_del_ii (to_list , ha -> addr , addr_len , addr_type ,
3526+ ignore_index );
3527+ }
3528+ }
3529+
3530+ static void __hw_addr_flush (struct list_head * list )
3531+ {
3532+ struct netdev_hw_addr * ha , * tmp ;
3533+
3534+ list_for_each_entry_safe (ha , tmp , list , list ) {
3535+ list_del_rcu (& ha -> list );
3536+ call_rcu (& ha -> rcu_head , ha_rcu_free );
3537+ }
3538+ }
3539+
3540+ /* Device addresses handling functions */
3541+
3542+ static void dev_addr_flush (struct net_device * dev )
3543+ {
3544+ /* rtnl_mutex must be held here */
3545+
3546+ __hw_addr_flush (& dev -> dev_addr_list );
3547+ dev -> dev_addr = NULL ;
3548+ }
3549+
3550+ static int dev_addr_init (struct net_device * dev )
3551+ {
3552+ unsigned char addr [MAX_ADDR_LEN ];
3553+ struct netdev_hw_addr * ha ;
3554+ int err ;
3555+
3556+ /* rtnl_mutex must be held here */
3557+
3558+ INIT_LIST_HEAD (& dev -> dev_addr_list );
3559+ memset (addr , 0 , sizeof (* addr ));
3560+ err = __hw_addr_add (& dev -> dev_addr_list , addr , sizeof (* addr ),
3561+ NETDEV_HW_ADDR_T_LAN );
3562+ if (!err ) {
3563+ /*
3564+ * Get the first (previously created) address from the list
3565+ * and set dev_addr pointer to this location.
3566+ */
3567+ ha = list_first_entry (& dev -> dev_addr_list ,
3568+ struct netdev_hw_addr , list );
3569+ dev -> dev_addr = ha -> addr ;
3570+ }
3571+ return err ;
3572+ }
3573+
3574+ /**
3575+ * dev_addr_add - Add a device address
3576+ * @dev: device
3577+ * @addr: address to add
3578+ * @addr_type: address type
3579+ *
3580+ * Add a device address to the device or increase the reference count if
3581+ * it already exists.
3582+ *
3583+ * The caller must hold the rtnl_mutex.
3584+ */
3585+ int dev_addr_add (struct net_device * dev , unsigned char * addr ,
3586+ unsigned char addr_type )
3587+ {
3588+ int err ;
3589+
3590+ ASSERT_RTNL ();
3591+
3592+ err = __hw_addr_add (& dev -> dev_addr_list , addr , dev -> addr_len ,
3593+ addr_type );
3594+ if (!err )
3595+ call_netdevice_notifiers (NETDEV_CHANGEADDR , dev );
3596+ return err ;
3597+ }
3598+ EXPORT_SYMBOL (dev_addr_add );
3599+
3600+ /**
3601+ * dev_addr_del - Release a device address.
3602+ * @dev: device
3603+ * @addr: address to delete
3604+ * @addr_type: address type
3605+ *
3606+ * Release reference to a device address and remove it from the device
3607+ * if the reference count drops to zero.
3608+ *
3609+ * The caller must hold the rtnl_mutex.
3610+ */
3611+ int dev_addr_del (struct net_device * dev , unsigned char * addr ,
3612+ unsigned char addr_type )
3613+ {
3614+ int err ;
3615+
3616+ ASSERT_RTNL ();
3617+
3618+ err = __hw_addr_del_ii (& dev -> dev_addr_list , addr , dev -> addr_len ,
3619+ addr_type , 0 );
3620+ if (!err )
3621+ call_netdevice_notifiers (NETDEV_CHANGEADDR , dev );
3622+ return err ;
3623+ }
3624+ EXPORT_SYMBOL (dev_addr_del );
3625+
3626+ /**
3627+ * dev_addr_add_multiple - Add device addresses from another device
3628+ * @to_dev: device to which addresses will be added
3629+ * @from_dev: device from which addresses will be added
3630+ * @addr_type: address type - 0 means type will be used from from_dev
3631+ *
3632+ * Add device addresses of the one device to another.
3633+ **
3634+ * The caller must hold the rtnl_mutex.
3635+ */
3636+ int dev_addr_add_multiple (struct net_device * to_dev ,
3637+ struct net_device * from_dev ,
3638+ unsigned char addr_type )
3639+ {
3640+ int err ;
3641+
3642+ ASSERT_RTNL ();
3643+
3644+ if (from_dev -> addr_len != to_dev -> addr_len )
3645+ return - EINVAL ;
3646+ err = __hw_addr_add_multiple_ii (& to_dev -> dev_addr_list ,
3647+ & from_dev -> dev_addr_list ,
3648+ to_dev -> addr_len , addr_type , 0 );
3649+ if (!err )
3650+ call_netdevice_notifiers (NETDEV_CHANGEADDR , to_dev );
3651+ return err ;
3652+ }
3653+ EXPORT_SYMBOL (dev_addr_add_multiple );
3654+
3655+ /**
3656+ * dev_addr_del_multiple - Delete device addresses by another device
3657+ * @to_dev: device where the addresses will be deleted
3658+ * @from_dev: device by which addresses the addresses will be deleted
3659+ * @addr_type: address type - 0 means type will used from from_dev
3660+ *
3661+ * Deletes addresses in to device by the list of addresses in from device.
3662+ *
3663+ * The caller must hold the rtnl_mutex.
3664+ */
3665+ int dev_addr_del_multiple (struct net_device * to_dev ,
3666+ struct net_device * from_dev ,
3667+ unsigned char addr_type )
3668+ {
3669+ ASSERT_RTNL ();
3670+
3671+ if (from_dev -> addr_len != to_dev -> addr_len )
3672+ return - EINVAL ;
3673+ __hw_addr_del_multiple_ii (& to_dev -> dev_addr_list ,
3674+ & from_dev -> dev_addr_list ,
3675+ to_dev -> addr_len , addr_type , 0 );
3676+ call_netdevice_notifiers (NETDEV_CHANGEADDR , to_dev );
3677+ return 0 ;
3678+ }
3679+ EXPORT_SYMBOL (dev_addr_del_multiple );
3680+
3681+ /* unicast and multicast addresses handling functions */
3682+
34373683int __dev_addr_delete (struct dev_addr_list * * list , int * count ,
34383684 void * addr , int alen , int glbl )
34393685{
@@ -4776,6 +5022,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
47765022
47775023 dev -> gso_max_size = GSO_MAX_SIZE ;
47785024
5025+ dev_addr_init (dev );
47795026 netdev_init_queues (dev );
47805027
47815028 INIT_LIST_HEAD (& dev -> napi_list );
@@ -4801,6 +5048,9 @@ void free_netdev(struct net_device *dev)
48015048
48025049 kfree (dev -> _tx );
48035050
5051+ /* Flush device addresses */
5052+ dev_addr_flush (dev );
5053+
48045054 list_for_each_entry_safe (p , n , & dev -> napi_list , dev_list )
48055055 netif_napi_del (p );
48065056
0 commit comments