aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c85
1 files changed, 75 insertions, 10 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 56b46579ff4..472676dd550 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -90,6 +90,7 @@
90#include <linux/if_ether.h> 90#include <linux/if_ether.h>
91#include <linux/netdevice.h> 91#include <linux/netdevice.h>
92#include <linux/etherdevice.h> 92#include <linux/etherdevice.h>
93#include <linux/ethtool.h>
93#include <linux/notifier.h> 94#include <linux/notifier.h>
94#include <linux/skbuff.h> 95#include <linux/skbuff.h>
95#include <net/net_namespace.h> 96#include <net/net_namespace.h>
@@ -961,6 +962,12 @@ void netdev_state_change(struct net_device *dev)
961 } 962 }
962} 963}
963 964
965void netdev_bonding_change(struct net_device *dev)
966{
967 call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, dev);
968}
969EXPORT_SYMBOL(netdev_bonding_change);
970
964/** 971/**
965 * dev_load - load a network module 972 * dev_load - load a network module
966 * @net: the applicable net namespace 973 * @net: the applicable net namespace
@@ -1117,6 +1124,29 @@ int dev_close(struct net_device *dev)
1117} 1124}
1118 1125
1119 1126
1127/**
1128 * dev_disable_lro - disable Large Receive Offload on a device
1129 * @dev: device
1130 *
1131 * Disable Large Receive Offload (LRO) on a net device. Must be
1132 * called under RTNL. This is needed if received packets may be
1133 * forwarded to another interface.
1134 */
1135void dev_disable_lro(struct net_device *dev)
1136{
1137 if (dev->ethtool_ops && dev->ethtool_ops->get_flags &&
1138 dev->ethtool_ops->set_flags) {
1139 u32 flags = dev->ethtool_ops->get_flags(dev);
1140 if (flags & ETH_FLAG_LRO) {
1141 flags &= ~ETH_FLAG_LRO;
1142 dev->ethtool_ops->set_flags(dev, flags);
1143 }
1144 }
1145 WARN_ON(dev->features & NETIF_F_LRO);
1146}
1147EXPORT_SYMBOL(dev_disable_lro);
1148
1149
1120static int dev_boot_phase = 1; 1150static int dev_boot_phase = 1;
1121 1151
1122/* 1152/*
@@ -2769,16 +2799,29 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
2769 return 0; 2799 return 0;
2770} 2800}
2771 2801
2772static void __dev_set_promiscuity(struct net_device *dev, int inc) 2802static int __dev_set_promiscuity(struct net_device *dev, int inc)
2773{ 2803{
2774 unsigned short old_flags = dev->flags; 2804 unsigned short old_flags = dev->flags;
2775 2805
2776 ASSERT_RTNL(); 2806 ASSERT_RTNL();
2777 2807
2778 if ((dev->promiscuity += inc) == 0) 2808 dev->flags |= IFF_PROMISC;
2779 dev->flags &= ~IFF_PROMISC; 2809 dev->promiscuity += inc;
2780 else 2810 if (dev->promiscuity == 0) {
2781 dev->flags |= IFF_PROMISC; 2811 /*
2812 * Avoid overflow.
2813 * If inc causes overflow, untouch promisc and return error.
2814 */
2815 if (inc < 0)
2816 dev->flags &= ~IFF_PROMISC;
2817 else {
2818 dev->promiscuity -= inc;
2819 printk(KERN_WARNING "%s: promiscuity touches roof, "
2820 "set promiscuity failed, promiscuity feature "
2821 "of device might be broken.\n", dev->name);
2822 return -EOVERFLOW;
2823 }
2824 }
2782 if (dev->flags != old_flags) { 2825 if (dev->flags != old_flags) {
2783 printk(KERN_INFO "device %s %s promiscuous mode\n", 2826 printk(KERN_INFO "device %s %s promiscuous mode\n",
2784 dev->name, (dev->flags & IFF_PROMISC) ? "entered" : 2827 dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
@@ -2796,6 +2839,7 @@ static void __dev_set_promiscuity(struct net_device *dev, int inc)
2796 if (dev->change_rx_flags) 2839 if (dev->change_rx_flags)
2797 dev->change_rx_flags(dev, IFF_PROMISC); 2840 dev->change_rx_flags(dev, IFF_PROMISC);
2798 } 2841 }
2842 return 0;
2799} 2843}
2800 2844
2801/** 2845/**
@@ -2807,14 +2851,19 @@ static void __dev_set_promiscuity(struct net_device *dev, int inc)
2807 * remains above zero the interface remains promiscuous. Once it hits zero 2851 * remains above zero the interface remains promiscuous. Once it hits zero
2808 * the device reverts back to normal filtering operation. A negative inc 2852 * the device reverts back to normal filtering operation. A negative inc
2809 * value is used to drop promiscuity on the device. 2853 * value is used to drop promiscuity on the device.
2854 * Return 0 if successful or a negative errno code on error.
2810 */ 2855 */
2811void dev_set_promiscuity(struct net_device *dev, int inc) 2856int dev_set_promiscuity(struct net_device *dev, int inc)
2812{ 2857{
2813 unsigned short old_flags = dev->flags; 2858 unsigned short old_flags = dev->flags;
2859 int err;
2814 2860
2815 __dev_set_promiscuity(dev, inc); 2861 err = __dev_set_promiscuity(dev, inc);
2862 if (!err)
2863 return err;
2816 if (dev->flags != old_flags) 2864 if (dev->flags != old_flags)
2817 dev_set_rx_mode(dev); 2865 dev_set_rx_mode(dev);
2866 return err;
2818} 2867}
2819 2868
2820/** 2869/**
@@ -2827,22 +2876,38 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
2827 * to all interfaces. Once it hits zero the device reverts back to normal 2876 * to all interfaces. Once it hits zero the device reverts back to normal
2828 * filtering operation. A negative @inc value is used to drop the counter 2877 * filtering operation. A negative @inc value is used to drop the counter
2829 * when releasing a resource needing all multicasts. 2878 * when releasing a resource needing all multicasts.
2879 * Return 0 if successful or a negative errno code on error.
2830 */ 2880 */
2831 2881
2832void dev_set_allmulti(struct net_device *dev, int inc) 2882int dev_set_allmulti(struct net_device *dev, int inc)
2833{ 2883{
2834 unsigned short old_flags = dev->flags; 2884 unsigned short old_flags = dev->flags;
2835 2885
2836 ASSERT_RTNL(); 2886 ASSERT_RTNL();
2837 2887
2838 dev->flags |= IFF_ALLMULTI; 2888 dev->flags |= IFF_ALLMULTI;
2839 if ((dev->allmulti += inc) == 0) 2889 dev->allmulti += inc;
2840 dev->flags &= ~IFF_ALLMULTI; 2890 if (dev->allmulti == 0) {
2891 /*
2892 * Avoid overflow.
2893 * If inc causes overflow, untouch allmulti and return error.
2894 */
2895 if (inc < 0)
2896 dev->flags &= ~IFF_ALLMULTI;
2897 else {
2898 dev->allmulti -= inc;
2899 printk(KERN_WARNING "%s: allmulti touches roof, "
2900 "set allmulti failed, allmulti feature of "
2901 "device might be broken.\n", dev->name);
2902 return -EOVERFLOW;
2903 }
2904 }
2841 if (dev->flags ^ old_flags) { 2905 if (dev->flags ^ old_flags) {
2842 if (dev->change_rx_flags) 2906 if (dev->change_rx_flags)
2843 dev->change_rx_flags(dev, IFF_ALLMULTI); 2907 dev->change_rx_flags(dev, IFF_ALLMULTI);
2844 dev_set_rx_mode(dev); 2908 dev_set_rx_mode(dev);
2845 } 2909 }
2910 return 0;
2846} 2911}
2847 2912
2848/* 2913/*