Commit 4bf84c35 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

net: add change_carrier netdev op

This allows a driver to register change_carrier callback which will be
called whenever user will like to change carrier state. This is useful
for devices like dummy, gre, team and so on.
Signed-off-by: default avatarJiri Pirko <jiri@resnulli.us>
Acked-by: default avatarFlavio Leitner <fbl@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b5a05550
...@@ -891,6 +891,14 @@ struct netdev_fcoe_hbainfo { ...@@ -891,6 +891,14 @@ struct netdev_fcoe_hbainfo {
* int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh)
* int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
* struct net_device *dev) * struct net_device *dev)
*
* int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier);
* Called to change device carrier. Soft-devices (like dummy, team, etc)
* which do not represent real hardware may define this to allow their
* userspace components to manage their virtual carrier state. Devices
* that determine carrier state from physical hardware properties (eg
* network cables) or protocol-dependent mechanisms (eg
* USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.
*/ */
struct net_device_ops { struct net_device_ops {
int (*ndo_init)(struct net_device *dev); int (*ndo_init)(struct net_device *dev);
...@@ -1008,6 +1016,8 @@ struct net_device_ops { ...@@ -1008,6 +1016,8 @@ struct net_device_ops {
int (*ndo_bridge_getlink)(struct sk_buff *skb, int (*ndo_bridge_getlink)(struct sk_buff *skb,
u32 pid, u32 seq, u32 pid, u32 seq,
struct net_device *dev); struct net_device *dev);
int (*ndo_change_carrier)(struct net_device *dev,
bool new_carrier);
}; };
/* /*
...@@ -2194,6 +2204,8 @@ extern int dev_set_mtu(struct net_device *, int); ...@@ -2194,6 +2204,8 @@ extern int dev_set_mtu(struct net_device *, int);
extern void dev_set_group(struct net_device *, int); extern void dev_set_group(struct net_device *, int);
extern int dev_set_mac_address(struct net_device *, extern int dev_set_mac_address(struct net_device *,
struct sockaddr *); struct sockaddr *);
extern int dev_change_carrier(struct net_device *,
bool new_carrier);
extern int dev_hard_start_xmit(struct sk_buff *skb, extern int dev_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
struct netdev_queue *txq); struct netdev_queue *txq);
......
...@@ -5027,6 +5027,25 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) ...@@ -5027,6 +5027,25 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
} }
EXPORT_SYMBOL(dev_set_mac_address); EXPORT_SYMBOL(dev_set_mac_address);
/**
* dev_change_carrier - Change device carrier
* @dev: device
* @new_carries: new value
*
* Change device carrier
*/
int dev_change_carrier(struct net_device *dev, bool new_carrier)
{
const struct net_device_ops *ops = dev->netdev_ops;
if (!ops->ndo_change_carrier)
return -EOPNOTSUPP;
if (!netif_device_present(dev))
return -ENODEV;
return ops->ndo_change_carrier(dev, new_carrier);
}
EXPORT_SYMBOL(dev_change_carrier);
/* /*
* Perform the SIOCxIFxxx calls, inside rcu_read_lock() * Perform the SIOCxIFxxx calls, inside rcu_read_lock()
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment