diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 78b5a89b0f4..35dfb831848 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1685,10 +1685,10 @@ EXPORT_SYMBOL(netif_device_attach); | |||
1685 | 1685 | ||
1686 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | 1686 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) |
1687 | { | 1687 | { |
1688 | return ((features & NETIF_F_GEN_CSUM) || | 1688 | return ((features & NETIF_F_NO_CSUM) || |
1689 | ((features & NETIF_F_IP_CSUM) && | 1689 | ((features & NETIF_F_V4_CSUM) && |
1690 | protocol == htons(ETH_P_IP)) || | 1690 | protocol == htons(ETH_P_IP)) || |
1691 | ((features & NETIF_F_IPV6_CSUM) && | 1691 | ((features & NETIF_F_V6_CSUM) && |
1692 | protocol == htons(ETH_P_IPV6)) || | 1692 | protocol == htons(ETH_P_IPV6)) || |
1693 | ((features & NETIF_F_FCOE_CRC) && | 1693 | ((features & NETIF_F_FCOE_CRC) && |
1694 | protocol == htons(ETH_P_FCOE))); | 1694 | protocol == htons(ETH_P_FCOE))); |
@@ -1696,22 +1696,18 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) | |||
1696 | 1696 | ||
1697 | static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) | 1697 | static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) |
1698 | { | 1698 | { |
1699 | __be16 protocol = skb->protocol; | ||
1699 | int features = dev->features; | 1700 | int features = dev->features; |
1700 | 1701 | ||
1701 | if (vlan_tx_tag_present(skb)) | 1702 | if (vlan_tx_tag_present(skb)) { |
1702 | features &= dev->vlan_features; | 1703 | features &= dev->vlan_features; |
1703 | 1704 | } else if (protocol == htons(ETH_P_8021Q)) { | |
1704 | if (can_checksum_protocol(features, skb->protocol)) | ||
1705 | return true; | ||
1706 | |||
1707 | if (skb->protocol == htons(ETH_P_8021Q)) { | ||
1708 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 1705 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
1709 | if (can_checksum_protocol(dev->features & dev->vlan_features, | 1706 | protocol = veh->h_vlan_encapsulated_proto; |
1710 | veh->h_vlan_encapsulated_proto)) | 1707 | features &= dev->vlan_features; |
1711 | return true; | ||
1712 | } | 1708 | } |
1713 | 1709 | ||
1714 | return false; | 1710 | return can_checksum_protocol(features, protocol); |
1715 | } | 1711 | } |
1716 | 1712 | ||
1717 | /** | 1713 | /** |
@@ -2213,7 +2209,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2213 | } | 2209 | } |
2214 | 2210 | ||
2215 | static DEFINE_PER_CPU(int, xmit_recursion); | 2211 | static DEFINE_PER_CPU(int, xmit_recursion); |
2216 | #define RECURSION_LIMIT 3 | 2212 | #define RECURSION_LIMIT 10 |
2217 | 2213 | ||
2218 | /** | 2214 | /** |
2219 | * dev_queue_xmit - transmit a buffer | 2215 | * dev_queue_xmit - transmit a buffer |
@@ -2413,7 +2409,7 @@ EXPORT_SYMBOL(__skb_get_rxhash); | |||
2413 | #ifdef CONFIG_RPS | 2409 | #ifdef CONFIG_RPS |
2414 | 2410 | ||
2415 | /* One global table that all flow-based protocols share. */ | 2411 | /* One global table that all flow-based protocols share. */ |
2416 | struct rps_sock_flow_table *rps_sock_flow_table __read_mostly; | 2412 | struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly; |
2417 | EXPORT_SYMBOL(rps_sock_flow_table); | 2413 | EXPORT_SYMBOL(rps_sock_flow_table); |
2418 | 2414 | ||
2419 | /* | 2415 | /* |
@@ -2425,7 +2421,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2425 | struct rps_dev_flow **rflowp) | 2421 | struct rps_dev_flow **rflowp) |
2426 | { | 2422 | { |
2427 | struct netdev_rx_queue *rxqueue; | 2423 | struct netdev_rx_queue *rxqueue; |
2428 | struct rps_map *map = NULL; | 2424 | struct rps_map *map; |
2429 | struct rps_dev_flow_table *flow_table; | 2425 | struct rps_dev_flow_table *flow_table; |
2430 | struct rps_sock_flow_table *sock_flow_table; | 2426 | struct rps_sock_flow_table *sock_flow_table; |
2431 | int cpu = -1; | 2427 | int cpu = -1; |
@@ -2444,15 +2440,15 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2444 | } else | 2440 | } else |
2445 | rxqueue = dev->_rx; | 2441 | rxqueue = dev->_rx; |
2446 | 2442 | ||
2447 | if (rxqueue->rps_map) { | 2443 | map = rcu_dereference(rxqueue->rps_map); |
2448 | map = rcu_dereference(rxqueue->rps_map); | 2444 | if (map) { |
2449 | if (map && map->len == 1) { | 2445 | if (map->len == 1) { |
2450 | tcpu = map->cpus[0]; | 2446 | tcpu = map->cpus[0]; |
2451 | if (cpu_online(tcpu)) | 2447 | if (cpu_online(tcpu)) |
2452 | cpu = tcpu; | 2448 | cpu = tcpu; |
2453 | goto done; | 2449 | goto done; |
2454 | } | 2450 | } |
2455 | } else if (!rxqueue->rps_flow_table) { | 2451 | } else if (!rcu_dereference_raw(rxqueue->rps_flow_table)) { |
2456 | goto done; | 2452 | goto done; |
2457 | } | 2453 | } |
2458 | 2454 | ||
@@ -5416,7 +5412,7 @@ void netdev_run_todo(void) | |||
5416 | /* paranoia */ | 5412 | /* paranoia */ |
5417 | BUG_ON(netdev_refcnt_read(dev)); | 5413 | BUG_ON(netdev_refcnt_read(dev)); |
5418 | WARN_ON(rcu_dereference_raw(dev->ip_ptr)); | 5414 | WARN_ON(rcu_dereference_raw(dev->ip_ptr)); |
5419 | WARN_ON(dev->ip6_ptr); | 5415 | WARN_ON(rcu_dereference_raw(dev->ip6_ptr)); |
5420 | WARN_ON(dev->dn_ptr); | 5416 | WARN_ON(dev->dn_ptr); |
5421 | 5417 | ||
5422 | if (dev->destructor) | 5418 | if (dev->destructor) |