aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2012-12-27 18:49:37 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-28 18:24:18 -0500
commit4bf84c35c65f36a344fb7a6cde6274df4120efb8 (patch)
tree09f7e45f4db6dc8fefd2910286aa3b0fcc5d50c2
parentb5a05550b76fe5b934b6f3b7f4b36ae9513745f6 (diff)
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: Jiri Pirko <jiri@resnulli.us> Acked-by: Flavio Leitner <fbl@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netdevice.h12
-rw-r--r--net/core/dev.c19
2 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c599e4782d45..0e1b92a0c1ec 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -891,6 +891,14 @@ struct netdev_fcoe_hbainfo {
891 * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) 891 * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh)
892 * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, 892 * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
893 * struct net_device *dev) 893 * struct net_device *dev)
894 *
895 * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier);
896 * Called to change device carrier. Soft-devices (like dummy, team, etc)
897 * which do not represent real hardware may define this to allow their
898 * userspace components to manage their virtual carrier state. Devices
899 * that determine carrier state from physical hardware properties (eg
900 * network cables) or protocol-dependent mechanisms (eg
901 * USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.
894 */ 902 */
895struct net_device_ops { 903struct net_device_ops {
896 int (*ndo_init)(struct net_device *dev); 904 int (*ndo_init)(struct net_device *dev);
@@ -1008,6 +1016,8 @@ struct net_device_ops {
1008 int (*ndo_bridge_getlink)(struct sk_buff *skb, 1016 int (*ndo_bridge_getlink)(struct sk_buff *skb,
1009 u32 pid, u32 seq, 1017 u32 pid, u32 seq,
1010 struct net_device *dev); 1018 struct net_device *dev);
1019 int (*ndo_change_carrier)(struct net_device *dev,
1020 bool new_carrier);
1011}; 1021};
1012 1022
1013/* 1023/*
@@ -2194,6 +2204,8 @@ extern int dev_set_mtu(struct net_device *, int);
2194extern void dev_set_group(struct net_device *, int); 2204extern void dev_set_group(struct net_device *, int);
2195extern int dev_set_mac_address(struct net_device *, 2205extern int dev_set_mac_address(struct net_device *,
2196 struct sockaddr *); 2206 struct sockaddr *);
2207extern int dev_change_carrier(struct net_device *,
2208 bool new_carrier);
2197extern int dev_hard_start_xmit(struct sk_buff *skb, 2209extern int dev_hard_start_xmit(struct sk_buff *skb,
2198 struct net_device *dev, 2210 struct net_device *dev,
2199 struct netdev_queue *txq); 2211 struct netdev_queue *txq);
diff --git a/net/core/dev.c b/net/core/dev.c
index 515473ee52cb..21c5b976dcf3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5027,6 +5027,25 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
5027} 5027}
5028EXPORT_SYMBOL(dev_set_mac_address); 5028EXPORT_SYMBOL(dev_set_mac_address);
5029 5029
5030/**
5031 * dev_change_carrier - Change device carrier
5032 * @dev: device
5033 * @new_carries: new value
5034 *
5035 * Change device carrier
5036 */
5037int dev_change_carrier(struct net_device *dev, bool new_carrier)
5038{
5039 const struct net_device_ops *ops = dev->netdev_ops;
5040
5041 if (!ops->ndo_change_carrier)
5042 return -EOPNOTSUPP;
5043 if (!netif_device_present(dev))
5044 return -ENODEV;
5045 return ops->ndo_change_carrier(dev, new_carrier);
5046}
5047EXPORT_SYMBOL(dev_change_carrier);
5048
5030/* 5049/*
5031 * Perform the SIOCxIFxxx calls, inside rcu_read_lock() 5050 * Perform the SIOCxIFxxx calls, inside rcu_read_lock()
5032 */ 5051 */