diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 230 |
1 files changed, 158 insertions, 72 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 0ae08d3f57e7..9174c77d3112 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -891,7 +891,7 @@ int dev_alloc_name(struct net_device *dev, const char *name) | |||
891 | * Change name of a device, can pass format strings "eth%d". | 891 | * Change name of a device, can pass format strings "eth%d". |
892 | * for wildcarding. | 892 | * for wildcarding. |
893 | */ | 893 | */ |
894 | int dev_change_name(struct net_device *dev, char *newname) | 894 | int dev_change_name(struct net_device *dev, const char *newname) |
895 | { | 895 | { |
896 | char oldname[IFNAMSIZ]; | 896 | char oldname[IFNAMSIZ]; |
897 | int err = 0; | 897 | int err = 0; |
@@ -917,7 +917,6 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
917 | err = dev_alloc_name(dev, newname); | 917 | err = dev_alloc_name(dev, newname); |
918 | if (err < 0) | 918 | if (err < 0) |
919 | return err; | 919 | return err; |
920 | strcpy(newname, dev->name); | ||
921 | } | 920 | } |
922 | else if (__dev_get_by_name(net, newname)) | 921 | else if (__dev_get_by_name(net, newname)) |
923 | return -EEXIST; | 922 | return -EEXIST; |
@@ -925,10 +924,10 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
925 | strlcpy(dev->name, newname, IFNAMSIZ); | 924 | strlcpy(dev->name, newname, IFNAMSIZ); |
926 | 925 | ||
927 | rollback: | 926 | rollback: |
928 | err = device_rename(&dev->dev, dev->name); | 927 | ret = device_rename(&dev->dev, dev->name); |
929 | if (err) { | 928 | if (ret) { |
930 | memcpy(dev->name, oldname, IFNAMSIZ); | 929 | memcpy(dev->name, oldname, IFNAMSIZ); |
931 | return err; | 930 | return ret; |
932 | } | 931 | } |
933 | 932 | ||
934 | write_lock_bh(&dev_base_lock); | 933 | write_lock_bh(&dev_base_lock); |
@@ -955,6 +954,38 @@ rollback: | |||
955 | } | 954 | } |
956 | 955 | ||
957 | /** | 956 | /** |
957 | * dev_set_alias - change ifalias of a device | ||
958 | * @dev: device | ||
959 | * @alias: name up to IFALIASZ | ||
960 | * @len: limit of bytes to copy from info | ||
961 | * | ||
962 | * Set ifalias for a device, | ||
963 | */ | ||
964 | int dev_set_alias(struct net_device *dev, const char *alias, size_t len) | ||
965 | { | ||
966 | ASSERT_RTNL(); | ||
967 | |||
968 | if (len >= IFALIASZ) | ||
969 | return -EINVAL; | ||
970 | |||
971 | if (!len) { | ||
972 | if (dev->ifalias) { | ||
973 | kfree(dev->ifalias); | ||
974 | dev->ifalias = NULL; | ||
975 | } | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | dev->ifalias = krealloc(dev->ifalias, len+1, GFP_KERNEL); | ||
980 | if (!dev->ifalias) | ||
981 | return -ENOMEM; | ||
982 | |||
983 | strlcpy(dev->ifalias, alias, len+1); | ||
984 | return len; | ||
985 | } | ||
986 | |||
987 | |||
988 | /** | ||
958 | * netdev_features_change - device changes features | 989 | * netdev_features_change - device changes features |
959 | * @dev: device to cause notification | 990 | * @dev: device to cause notification |
960 | * | 991 | * |
@@ -1676,14 +1707,14 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) | |||
1676 | } | 1707 | } |
1677 | 1708 | ||
1678 | switch (skb->protocol) { | 1709 | switch (skb->protocol) { |
1679 | case __constant_htons(ETH_P_IP): | 1710 | case htons(ETH_P_IP): |
1680 | if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET))) | 1711 | if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET))) |
1681 | ip_proto = ip_hdr(skb)->protocol; | 1712 | ip_proto = ip_hdr(skb)->protocol; |
1682 | addr1 = ip_hdr(skb)->saddr; | 1713 | addr1 = ip_hdr(skb)->saddr; |
1683 | addr2 = ip_hdr(skb)->daddr; | 1714 | addr2 = ip_hdr(skb)->daddr; |
1684 | ihl = ip_hdr(skb)->ihl; | 1715 | ihl = ip_hdr(skb)->ihl; |
1685 | break; | 1716 | break; |
1686 | case __constant_htons(ETH_P_IPV6): | 1717 | case htons(ETH_P_IPV6): |
1687 | ip_proto = ipv6_hdr(skb)->nexthdr; | 1718 | ip_proto = ipv6_hdr(skb)->nexthdr; |
1688 | addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3]; | 1719 | addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3]; |
1689 | addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3]; | 1720 | addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3]; |
@@ -2187,6 +2218,9 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2187 | int ret = NET_RX_DROP; | 2218 | int ret = NET_RX_DROP; |
2188 | __be16 type; | 2219 | __be16 type; |
2189 | 2220 | ||
2221 | if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) | ||
2222 | return NET_RX_SUCCESS; | ||
2223 | |||
2190 | /* if we've gotten here through NAPI, check netpoll */ | 2224 | /* if we've gotten here through NAPI, check netpoll */ |
2191 | if (netpoll_receive_skb(skb)) | 2225 | if (netpoll_receive_skb(skb)) |
2192 | return NET_RX_DROP; | 2226 | return NET_RX_DROP; |
@@ -3306,6 +3340,12 @@ static void dev_addr_discard(struct net_device *dev) | |||
3306 | netif_addr_unlock_bh(dev); | 3340 | netif_addr_unlock_bh(dev); |
3307 | } | 3341 | } |
3308 | 3342 | ||
3343 | /** | ||
3344 | * dev_get_flags - get flags reported to userspace | ||
3345 | * @dev: device | ||
3346 | * | ||
3347 | * Get the combination of flag bits exported through APIs to userspace. | ||
3348 | */ | ||
3309 | unsigned dev_get_flags(const struct net_device *dev) | 3349 | unsigned dev_get_flags(const struct net_device *dev) |
3310 | { | 3350 | { |
3311 | unsigned flags; | 3351 | unsigned flags; |
@@ -3330,6 +3370,14 @@ unsigned dev_get_flags(const struct net_device *dev) | |||
3330 | return flags; | 3370 | return flags; |
3331 | } | 3371 | } |
3332 | 3372 | ||
3373 | /** | ||
3374 | * dev_change_flags - change device settings | ||
3375 | * @dev: device | ||
3376 | * @flags: device state flags | ||
3377 | * | ||
3378 | * Change settings on device based state flags. The flags are | ||
3379 | * in the userspace exported format. | ||
3380 | */ | ||
3333 | int dev_change_flags(struct net_device *dev, unsigned flags) | 3381 | int dev_change_flags(struct net_device *dev, unsigned flags) |
3334 | { | 3382 | { |
3335 | int ret, changes; | 3383 | int ret, changes; |
@@ -3399,6 +3447,13 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
3399 | return ret; | 3447 | return ret; |
3400 | } | 3448 | } |
3401 | 3449 | ||
3450 | /** | ||
3451 | * dev_set_mtu - Change maximum transfer unit | ||
3452 | * @dev: device | ||
3453 | * @new_mtu: new transfer unit | ||
3454 | * | ||
3455 | * Change the maximum transfer size of the network device. | ||
3456 | */ | ||
3402 | int dev_set_mtu(struct net_device *dev, int new_mtu) | 3457 | int dev_set_mtu(struct net_device *dev, int new_mtu) |
3403 | { | 3458 | { |
3404 | int err; | 3459 | int err; |
@@ -3423,6 +3478,13 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) | |||
3423 | return err; | 3478 | return err; |
3424 | } | 3479 | } |
3425 | 3480 | ||
3481 | /** | ||
3482 | * dev_set_mac_address - Change Media Access Control Address | ||
3483 | * @dev: device | ||
3484 | * @sa: new address | ||
3485 | * | ||
3486 | * Change the hardware (MAC) address of the device | ||
3487 | */ | ||
3426 | int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | 3488 | int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) |
3427 | { | 3489 | { |
3428 | int err; | 3490 | int err; |
@@ -3888,6 +3950,46 @@ static void netdev_init_queue_locks(struct net_device *dev) | |||
3888 | __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL); | 3950 | __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL); |
3889 | } | 3951 | } |
3890 | 3952 | ||
3953 | unsigned long netdev_fix_features(unsigned long features, const char *name) | ||
3954 | { | ||
3955 | /* Fix illegal SG+CSUM combinations. */ | ||
3956 | if ((features & NETIF_F_SG) && | ||
3957 | !(features & NETIF_F_ALL_CSUM)) { | ||
3958 | if (name) | ||
3959 | printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no " | ||
3960 | "checksum feature.\n", name); | ||
3961 | features &= ~NETIF_F_SG; | ||
3962 | } | ||
3963 | |||
3964 | /* TSO requires that SG is present as well. */ | ||
3965 | if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) { | ||
3966 | if (name) | ||
3967 | printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no " | ||
3968 | "SG feature.\n", name); | ||
3969 | features &= ~NETIF_F_TSO; | ||
3970 | } | ||
3971 | |||
3972 | if (features & NETIF_F_UFO) { | ||
3973 | if (!(features & NETIF_F_GEN_CSUM)) { | ||
3974 | if (name) | ||
3975 | printk(KERN_ERR "%s: Dropping NETIF_F_UFO " | ||
3976 | "since no NETIF_F_HW_CSUM feature.\n", | ||
3977 | name); | ||
3978 | features &= ~NETIF_F_UFO; | ||
3979 | } | ||
3980 | |||
3981 | if (!(features & NETIF_F_SG)) { | ||
3982 | if (name) | ||
3983 | printk(KERN_ERR "%s: Dropping NETIF_F_UFO " | ||
3984 | "since no NETIF_F_SG feature.\n", name); | ||
3985 | features &= ~NETIF_F_UFO; | ||
3986 | } | ||
3987 | } | ||
3988 | |||
3989 | return features; | ||
3990 | } | ||
3991 | EXPORT_SYMBOL(netdev_fix_features); | ||
3992 | |||
3891 | /** | 3993 | /** |
3892 | * register_netdevice - register a network device | 3994 | * register_netdevice - register a network device |
3893 | * @dev: device to register | 3995 | * @dev: device to register |
@@ -3973,36 +4075,7 @@ int register_netdevice(struct net_device *dev) | |||
3973 | dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); | 4075 | dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); |
3974 | } | 4076 | } |
3975 | 4077 | ||
3976 | 4078 | dev->features = netdev_fix_features(dev->features, dev->name); | |
3977 | /* Fix illegal SG+CSUM combinations. */ | ||
3978 | if ((dev->features & NETIF_F_SG) && | ||
3979 | !(dev->features & NETIF_F_ALL_CSUM)) { | ||
3980 | printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n", | ||
3981 | dev->name); | ||
3982 | dev->features &= ~NETIF_F_SG; | ||
3983 | } | ||
3984 | |||
3985 | /* TSO requires that SG is present as well. */ | ||
3986 | if ((dev->features & NETIF_F_TSO) && | ||
3987 | !(dev->features & NETIF_F_SG)) { | ||
3988 | printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no SG feature.\n", | ||
3989 | dev->name); | ||
3990 | dev->features &= ~NETIF_F_TSO; | ||
3991 | } | ||
3992 | if (dev->features & NETIF_F_UFO) { | ||
3993 | if (!(dev->features & NETIF_F_HW_CSUM)) { | ||
3994 | printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no " | ||
3995 | "NETIF_F_HW_CSUM feature.\n", | ||
3996 | dev->name); | ||
3997 | dev->features &= ~NETIF_F_UFO; | ||
3998 | } | ||
3999 | if (!(dev->features & NETIF_F_SG)) { | ||
4000 | printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no " | ||
4001 | "NETIF_F_SG feature.\n", | ||
4002 | dev->name); | ||
4003 | dev->features &= ~NETIF_F_UFO; | ||
4004 | } | ||
4005 | } | ||
4006 | 4079 | ||
4007 | /* Enable software GSO if SG is supported. */ | 4080 | /* Enable software GSO if SG is supported. */ |
4008 | if (dev->features & NETIF_F_SG) | 4081 | if (dev->features & NETIF_F_SG) |
@@ -4311,7 +4384,12 @@ void free_netdev(struct net_device *dev) | |||
4311 | put_device(&dev->dev); | 4384 | put_device(&dev->dev); |
4312 | } | 4385 | } |
4313 | 4386 | ||
4314 | /* Synchronize with packet receive processing. */ | 4387 | /** |
4388 | * synchronize_net - Synchronize with packet receive processing | ||
4389 | * | ||
4390 | * Wait for packets currently being received to be done. | ||
4391 | * Does not block later packets from starting. | ||
4392 | */ | ||
4315 | void synchronize_net(void) | 4393 | void synchronize_net(void) |
4316 | { | 4394 | { |
4317 | might_sleep(); | 4395 | might_sleep(); |
@@ -4613,7 +4691,7 @@ netdev_dma_event(struct dma_client *client, struct dma_chan *chan, | |||
4613 | } | 4691 | } |
4614 | 4692 | ||
4615 | /** | 4693 | /** |
4616 | * netdev_dma_regiser - register the networking subsystem as a DMA client | 4694 | * netdev_dma_register - register the networking subsystem as a DMA client |
4617 | */ | 4695 | */ |
4618 | static int __init netdev_dma_register(void) | 4696 | static int __init netdev_dma_register(void) |
4619 | { | 4697 | { |
@@ -4636,43 +4714,45 @@ static int __init netdev_dma_register(void) { return -ENODEV; } | |||
4636 | #endif /* CONFIG_NET_DMA */ | 4714 | #endif /* CONFIG_NET_DMA */ |
4637 | 4715 | ||
4638 | /** | 4716 | /** |
4639 | * netdev_compute_feature - compute conjunction of two feature sets | 4717 | * netdev_increment_features - increment feature set by one |
4640 | * @all: first feature set | 4718 | * @all: current feature set |
4641 | * @one: second feature set | 4719 | * @one: new feature set |
4720 | * @mask: mask feature set | ||
4642 | * | 4721 | * |
4643 | * Computes a new feature set after adding a device with feature set | 4722 | * Computes a new feature set after adding a device with feature set |
4644 | * @one to the master device with current feature set @all. Returns | 4723 | * @one to the master device with current feature set @all. Will not |
4645 | * the new feature set. | 4724 | * enable anything that is off in @mask. Returns the new feature set. |
4646 | */ | 4725 | */ |
4647 | int netdev_compute_features(unsigned long all, unsigned long one) | 4726 | unsigned long netdev_increment_features(unsigned long all, unsigned long one, |
4648 | { | 4727 | unsigned long mask) |
4649 | /* if device needs checksumming, downgrade to hw checksumming */ | 4728 | { |
4650 | if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) | 4729 | /* If device needs checksumming, downgrade to it. */ |
4651 | all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; | 4730 | if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) |
4652 | 4731 | all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM); | |
4653 | /* if device can't do all checksum, downgrade to ipv4/ipv6 */ | 4732 | else if (mask & NETIF_F_ALL_CSUM) { |
4654 | if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM)) | 4733 | /* If one device supports v4/v6 checksumming, set for all. */ |
4655 | all ^= NETIF_F_HW_CSUM | 4734 | if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) && |
4656 | | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | 4735 | !(all & NETIF_F_GEN_CSUM)) { |
4657 | 4736 | all &= ~NETIF_F_ALL_CSUM; | |
4658 | if (one & NETIF_F_GSO) | 4737 | all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); |
4659 | one |= NETIF_F_GSO_SOFTWARE; | 4738 | } |
4660 | one |= NETIF_F_GSO; | ||
4661 | 4739 | ||
4662 | /* If even one device supports robust GSO, enable it for all. */ | 4740 | /* If one device supports hw checksumming, set for all. */ |
4663 | if (one & NETIF_F_GSO_ROBUST) | 4741 | if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) { |
4664 | all |= NETIF_F_GSO_ROBUST; | 4742 | all &= ~NETIF_F_ALL_CSUM; |
4743 | all |= NETIF_F_HW_CSUM; | ||
4744 | } | ||
4745 | } | ||
4665 | 4746 | ||
4666 | all &= one | NETIF_F_LLTX; | 4747 | one |= NETIF_F_ALL_CSUM; |
4667 | 4748 | ||
4668 | if (!(all & NETIF_F_ALL_CSUM)) | 4749 | one |= all & NETIF_F_ONE_FOR_ALL; |
4669 | all &= ~NETIF_F_SG; | 4750 | all &= one | NETIF_F_LLTX | NETIF_F_GSO; |
4670 | if (!(all & NETIF_F_SG)) | 4751 | all |= one & mask & NETIF_F_ONE_FOR_ALL; |
4671 | all &= ~NETIF_F_GSO_MASK; | ||
4672 | 4752 | ||
4673 | return all; | 4753 | return all; |
4674 | } | 4754 | } |
4675 | EXPORT_SYMBOL(netdev_compute_features); | 4755 | EXPORT_SYMBOL(netdev_increment_features); |
4676 | 4756 | ||
4677 | static struct hlist_head *netdev_create_hash(void) | 4757 | static struct hlist_head *netdev_create_hash(void) |
4678 | { | 4758 | { |
@@ -4708,10 +4788,18 @@ err_name: | |||
4708 | return -ENOMEM; | 4788 | return -ENOMEM; |
4709 | } | 4789 | } |
4710 | 4790 | ||
4711 | char *netdev_drivername(struct net_device *dev, char *buffer, int len) | 4791 | /** |
4792 | * netdev_drivername - network driver for the device | ||
4793 | * @dev: network device | ||
4794 | * @buffer: buffer for resulting name | ||
4795 | * @len: size of buffer | ||
4796 | * | ||
4797 | * Determine network driver for device. | ||
4798 | */ | ||
4799 | char *netdev_drivername(const struct net_device *dev, char *buffer, int len) | ||
4712 | { | 4800 | { |
4713 | struct device_driver *driver; | 4801 | const struct device_driver *driver; |
4714 | struct device *parent; | 4802 | const struct device *parent; |
4715 | 4803 | ||
4716 | if (len <= 0 || !buffer) | 4804 | if (len <= 0 || !buffer) |
4717 | return buffer; | 4805 | return buffer; |
@@ -4878,8 +4966,6 @@ EXPORT_SYMBOL(br_fdb_get_hook); | |||
4878 | EXPORT_SYMBOL(br_fdb_put_hook); | 4966 | EXPORT_SYMBOL(br_fdb_put_hook); |
4879 | #endif | 4967 | #endif |
4880 | 4968 | ||
4881 | #ifdef CONFIG_KMOD | ||
4882 | EXPORT_SYMBOL(dev_load); | 4969 | EXPORT_SYMBOL(dev_load); |
4883 | #endif | ||
4884 | 4970 | ||
4885 | EXPORT_PER_CPU_SYMBOL(softnet_data); | 4971 | EXPORT_PER_CPU_SYMBOL(softnet_data); |