diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index a1607bc0cd4c..c421a1f8f0b9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -119,6 +119,7 @@ | |||
| 119 | #include <linux/err.h> | 119 | #include <linux/err.h> |
| 120 | #include <linux/ctype.h> | 120 | #include <linux/ctype.h> |
| 121 | #include <linux/if_arp.h> | 121 | #include <linux/if_arp.h> |
| 122 | #include <linux/if_vlan.h> | ||
| 122 | 123 | ||
| 123 | #include "net-sysfs.h" | 124 | #include "net-sysfs.h" |
| 124 | 125 | ||
| @@ -903,7 +904,11 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
| 903 | strlcpy(dev->name, newname, IFNAMSIZ); | 904 | strlcpy(dev->name, newname, IFNAMSIZ); |
| 904 | 905 | ||
| 905 | rollback: | 906 | rollback: |
| 906 | device_rename(&dev->dev, dev->name); | 907 | err = device_rename(&dev->dev, dev->name); |
| 908 | if (err) { | ||
| 909 | memcpy(dev->name, oldname, IFNAMSIZ); | ||
| 910 | return err; | ||
| 911 | } | ||
| 907 | 912 | ||
| 908 | write_lock_bh(&dev_base_lock); | 913 | write_lock_bh(&dev_base_lock); |
| 909 | hlist_del(&dev->name_hlist); | 914 | hlist_del(&dev->name_hlist); |
| @@ -1358,6 +1363,29 @@ void netif_device_attach(struct net_device *dev) | |||
| 1358 | } | 1363 | } |
| 1359 | EXPORT_SYMBOL(netif_device_attach); | 1364 | EXPORT_SYMBOL(netif_device_attach); |
| 1360 | 1365 | ||
| 1366 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | ||
| 1367 | { | ||
| 1368 | return ((features & NETIF_F_GEN_CSUM) || | ||
| 1369 | ((features & NETIF_F_IP_CSUM) && | ||
| 1370 | protocol == htons(ETH_P_IP)) || | ||
| 1371 | ((features & NETIF_F_IPV6_CSUM) && | ||
| 1372 | protocol == htons(ETH_P_IPV6))); | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) | ||
| 1376 | { | ||
| 1377 | if (can_checksum_protocol(dev->features, skb->protocol)) | ||
| 1378 | return true; | ||
| 1379 | |||
| 1380 | if (skb->protocol == htons(ETH_P_8021Q)) { | ||
| 1381 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
| 1382 | if (can_checksum_protocol(dev->features & dev->vlan_features, | ||
| 1383 | veh->h_vlan_encapsulated_proto)) | ||
| 1384 | return true; | ||
| 1385 | } | ||
| 1386 | |||
| 1387 | return false; | ||
| 1388 | } | ||
| 1361 | 1389 | ||
| 1362 | /* | 1390 | /* |
| 1363 | * Invalidate hardware checksum when packet is to be mangled, and | 1391 | * Invalidate hardware checksum when packet is to be mangled, and |
| @@ -1636,14 +1664,8 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
| 1636 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1664 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1637 | skb_set_transport_header(skb, skb->csum_start - | 1665 | skb_set_transport_header(skb, skb->csum_start - |
| 1638 | skb_headroom(skb)); | 1666 | skb_headroom(skb)); |
| 1639 | 1667 | if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb)) | |
| 1640 | if (!(dev->features & NETIF_F_GEN_CSUM) && | 1668 | goto out_kfree_skb; |
| 1641 | !((dev->features & NETIF_F_IP_CSUM) && | ||
| 1642 | skb->protocol == htons(ETH_P_IP)) && | ||
| 1643 | !((dev->features & NETIF_F_IPV6_CSUM) && | ||
| 1644 | skb->protocol == htons(ETH_P_IPV6))) | ||
| 1645 | if (skb_checksum_help(skb)) | ||
| 1646 | goto out_kfree_skb; | ||
| 1647 | } | 1669 | } |
| 1648 | 1670 | ||
| 1649 | gso: | 1671 | gso: |
| @@ -2055,6 +2077,10 @@ int netif_receive_skb(struct sk_buff *skb) | |||
| 2055 | 2077 | ||
| 2056 | rcu_read_lock(); | 2078 | rcu_read_lock(); |
| 2057 | 2079 | ||
| 2080 | /* Don't receive packets in an exiting network namespace */ | ||
| 2081 | if (!net_alive(dev_net(skb->dev))) | ||
| 2082 | goto out; | ||
| 2083 | |||
| 2058 | #ifdef CONFIG_NET_CLS_ACT | 2084 | #ifdef CONFIG_NET_CLS_ACT |
| 2059 | if (skb->tc_verd & TC_NCLS) { | 2085 | if (skb->tc_verd & TC_NCLS) { |
| 2060 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); | 2086 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); |
| @@ -3137,7 +3163,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
| 3137 | * Load in the correct multicast list now the flags have changed. | 3163 | * Load in the correct multicast list now the flags have changed. |
| 3138 | */ | 3164 | */ |
| 3139 | 3165 | ||
| 3140 | if (dev->change_rx_flags && (dev->flags ^ flags) & IFF_MULTICAST) | 3166 | if (dev->change_rx_flags && (old_flags ^ flags) & IFF_MULTICAST) |
| 3141 | dev->change_rx_flags(dev, IFF_MULTICAST); | 3167 | dev->change_rx_flags(dev, IFF_MULTICAST); |
| 3142 | 3168 | ||
| 3143 | dev_set_rx_mode(dev); | 3169 | dev_set_rx_mode(dev); |
