diff options
| -rw-r--r-- | net/core/rtnetlink.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 61ac8d06292c..ecb02afd52dc 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -504,7 +504,7 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, | |||
| 504 | 504 | ||
| 505 | EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo); | 505 | EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo); |
| 506 | 506 | ||
| 507 | static void set_operstate(struct net_device *dev, unsigned char transition) | 507 | static int set_operstate(struct net_device *dev, unsigned char transition, bool send_notification) |
| 508 | { | 508 | { |
| 509 | unsigned char operstate = dev->operstate; | 509 | unsigned char operstate = dev->operstate; |
| 510 | 510 | ||
| @@ -527,8 +527,12 @@ static void set_operstate(struct net_device *dev, unsigned char transition) | |||
| 527 | write_lock_bh(&dev_base_lock); | 527 | write_lock_bh(&dev_base_lock); |
| 528 | dev->operstate = operstate; | 528 | dev->operstate = operstate; |
| 529 | write_unlock_bh(&dev_base_lock); | 529 | write_unlock_bh(&dev_base_lock); |
| 530 | netdev_state_change(dev); | 530 | |
| 531 | } | 531 | if (send_notification) |
| 532 | netdev_state_change(dev); | ||
| 533 | return 1; | ||
| 534 | } else | ||
| 535 | return 0; | ||
| 532 | } | 536 | } |
| 533 | 537 | ||
| 534 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | 538 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, |
| @@ -822,6 +826,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
| 822 | if (tb[IFLA_BROADCAST]) { | 826 | if (tb[IFLA_BROADCAST]) { |
| 823 | nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); | 827 | nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); |
| 824 | send_addr_notify = 1; | 828 | send_addr_notify = 1; |
| 829 | modified = 1; | ||
| 825 | } | 830 | } |
| 826 | 831 | ||
| 827 | if (ifm->ifi_flags || ifm->ifi_change) { | 832 | if (ifm->ifi_flags || ifm->ifi_change) { |
| @@ -834,16 +839,23 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
| 834 | dev_change_flags(dev, flags); | 839 | dev_change_flags(dev, flags); |
| 835 | } | 840 | } |
| 836 | 841 | ||
| 837 | if (tb[IFLA_TXQLEN]) | 842 | if (tb[IFLA_TXQLEN]) { |
| 838 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); | 843 | if (dev->tx_queue_len != nla_get_u32(tb[IFLA_TXQLEN])) { |
| 844 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); | ||
| 845 | modified = 1; | ||
| 846 | } | ||
| 847 | } | ||
| 839 | 848 | ||
| 840 | if (tb[IFLA_OPERSTATE]) | 849 | if (tb[IFLA_OPERSTATE]) |
| 841 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); | 850 | modified |= set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), false); |
| 842 | 851 | ||
| 843 | if (tb[IFLA_LINKMODE]) { | 852 | if (tb[IFLA_LINKMODE]) { |
| 844 | write_lock_bh(&dev_base_lock); | 853 | if (dev->link_mode != nla_get_u8(tb[IFLA_LINKMODE])) { |
| 845 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); | 854 | write_lock_bh(&dev_base_lock); |
| 846 | write_unlock_bh(&dev_base_lock); | 855 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); |
| 856 | write_lock_bh(&dev_base_lock); | ||
| 857 | modified = 1; | ||
| 858 | } | ||
| 847 | } | 859 | } |
| 848 | 860 | ||
| 849 | err = 0; | 861 | err = 0; |
| @@ -857,6 +869,10 @@ errout: | |||
| 857 | 869 | ||
| 858 | if (send_addr_notify) | 870 | if (send_addr_notify) |
| 859 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 871 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
| 872 | |||
| 873 | if (modified) | ||
| 874 | netdev_state_change(dev); | ||
| 875 | |||
| 860 | return err; | 876 | return err; |
| 861 | } | 877 | } |
| 862 | 878 | ||
| @@ -974,7 +990,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname, | |||
| 974 | if (tb[IFLA_TXQLEN]) | 990 | if (tb[IFLA_TXQLEN]) |
| 975 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); | 991 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); |
| 976 | if (tb[IFLA_OPERSTATE]) | 992 | if (tb[IFLA_OPERSTATE]) |
| 977 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); | 993 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), true); |
| 978 | if (tb[IFLA_LINKMODE]) | 994 | if (tb[IFLA_LINKMODE]) |
| 979 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); | 995 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); |
| 980 | 996 | ||
