mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-18 20:04:16 +08:00
net: split eth_mac_addr for better error handling
When we set mac address, software mac address in system and hardware mac address all need to be updated. Current eth_mac_addr() doesn't allow callers to implement error handling nicely. This patch split eth_mac_addr() to prepare part and real commit part, then we can prepare first, and try to change hardware address, then do the real commit if hardware address is set successfully. Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com> Signed-off-by: Amos Kong <akong@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
40cbfc3707
commit
fa0879e37b
@ -40,6 +40,8 @@ extern int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
|
|||||||
extern void eth_header_cache_update(struct hh_cache *hh,
|
extern void eth_header_cache_update(struct hh_cache *hh,
|
||||||
const struct net_device *dev,
|
const struct net_device *dev,
|
||||||
const unsigned char *haddr);
|
const unsigned char *haddr);
|
||||||
|
extern int eth_prepare_mac_addr_change(struct net_device *dev, void *p);
|
||||||
|
extern void eth_commit_mac_addr_change(struct net_device *dev, void *p);
|
||||||
extern int eth_mac_addr(struct net_device *dev, void *p);
|
extern int eth_mac_addr(struct net_device *dev, void *p);
|
||||||
extern int eth_change_mtu(struct net_device *dev, int new_mtu);
|
extern int eth_change_mtu(struct net_device *dev, int new_mtu);
|
||||||
extern int eth_validate_addr(struct net_device *dev);
|
extern int eth_validate_addr(struct net_device *dev);
|
||||||
|
@ -271,6 +271,36 @@ void eth_header_cache_update(struct hh_cache *hh,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(eth_header_cache_update);
|
EXPORT_SYMBOL(eth_header_cache_update);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eth_prepare_mac_addr_change - prepare for mac change
|
||||||
|
* @dev: network device
|
||||||
|
* @p: socket address
|
||||||
|
*/
|
||||||
|
int eth_prepare_mac_addr_change(struct net_device *dev, void *p)
|
||||||
|
{
|
||||||
|
struct sockaddr *addr = p;
|
||||||
|
|
||||||
|
if (!(dev->priv_flags & IFF_LIVE_ADDR_CHANGE) && netif_running(dev))
|
||||||
|
return -EBUSY;
|
||||||
|
if (!is_valid_ether_addr(addr->sa_data))
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(eth_prepare_mac_addr_change);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eth_commit_mac_addr_change - commit mac change
|
||||||
|
* @dev: network device
|
||||||
|
* @p: socket address
|
||||||
|
*/
|
||||||
|
void eth_commit_mac_addr_change(struct net_device *dev, void *p)
|
||||||
|
{
|
||||||
|
struct sockaddr *addr = p;
|
||||||
|
|
||||||
|
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(eth_commit_mac_addr_change);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eth_mac_addr - set new Ethernet hardware address
|
* eth_mac_addr - set new Ethernet hardware address
|
||||||
* @dev: network device
|
* @dev: network device
|
||||||
@ -283,13 +313,12 @@ EXPORT_SYMBOL(eth_header_cache_update);
|
|||||||
*/
|
*/
|
||||||
int eth_mac_addr(struct net_device *dev, void *p)
|
int eth_mac_addr(struct net_device *dev, void *p)
|
||||||
{
|
{
|
||||||
struct sockaddr *addr = p;
|
int ret;
|
||||||
|
|
||||||
if (!(dev->priv_flags & IFF_LIVE_ADDR_CHANGE) && netif_running(dev))
|
ret = eth_prepare_mac_addr_change(dev, p);
|
||||||
return -EBUSY;
|
if (ret < 0)
|
||||||
if (!is_valid_ether_addr(addr->sa_data))
|
return ret;
|
||||||
return -EADDRNOTAVAIL;
|
eth_commit_mac_addr_change(dev, p);
|
||||||
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(eth_mac_addr);
|
EXPORT_SYMBOL(eth_mac_addr);
|
||||||
|
Loading…
Reference in New Issue
Block a user