diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 0cb3fe8d8e72..89e33a5d4d93 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1055,6 +1055,8 @@ rollback: | |||
1055 | */ | 1055 | */ |
1056 | int dev_set_alias(struct net_device *dev, const char *alias, size_t len) | 1056 | int dev_set_alias(struct net_device *dev, const char *alias, size_t len) |
1057 | { | 1057 | { |
1058 | char *new_ifalias; | ||
1059 | |||
1058 | ASSERT_RTNL(); | 1060 | ASSERT_RTNL(); |
1059 | 1061 | ||
1060 | if (len >= IFALIASZ) | 1062 | if (len >= IFALIASZ) |
@@ -1068,9 +1070,10 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len) | |||
1068 | return 0; | 1070 | return 0; |
1069 | } | 1071 | } |
1070 | 1072 | ||
1071 | dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); | 1073 | new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); |
1072 | if (!dev->ifalias) | 1074 | if (!new_ifalias) |
1073 | return -ENOMEM; | 1075 | return -ENOMEM; |
1076 | dev->ifalias = new_ifalias; | ||
1074 | 1077 | ||
1075 | strlcpy(dev->ifalias, alias, len+1); | 1078 | strlcpy(dev->ifalias, alias, len+1); |
1076 | return len; | 1079 | return len; |
@@ -1639,6 +1642,19 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
1639 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 1642 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
1640 | } | 1643 | } |
1641 | 1644 | ||
1645 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | ||
1646 | { | ||
1647 | if (ptype->af_packet_priv == NULL) | ||
1648 | return false; | ||
1649 | |||
1650 | if (ptype->id_match) | ||
1651 | return ptype->id_match(ptype, skb->sk); | ||
1652 | else if ((struct sock *)ptype->af_packet_priv == skb->sk) | ||
1653 | return true; | ||
1654 | |||
1655 | return false; | ||
1656 | } | ||
1657 | |||
1642 | /* | 1658 | /* |
1643 | * Support routine. Sends outgoing frames to any network | 1659 | * Support routine. Sends outgoing frames to any network |
1644 | * taps currently in use. | 1660 | * taps currently in use. |
@@ -1656,8 +1672,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1656 | * they originated from - MvS (miquels@drinkel.ow.org) | 1672 | * they originated from - MvS (miquels@drinkel.ow.org) |
1657 | */ | 1673 | */ |
1658 | if ((ptype->dev == dev || !ptype->dev) && | 1674 | if ((ptype->dev == dev || !ptype->dev) && |
1659 | (ptype->af_packet_priv == NULL || | 1675 | (!skb_loop_sk(ptype, skb))) { |
1660 | (struct sock *)ptype->af_packet_priv != skb->sk)) { | ||
1661 | if (pt_prev) { | 1676 | if (pt_prev) { |
1662 | deliver_skb(skb2, pt_prev, skb->dev); | 1677 | deliver_skb(skb2, pt_prev, skb->dev); |
1663 | pt_prev = ptype; | 1678 | pt_prev = ptype; |
@@ -2119,7 +2134,8 @@ static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) | |||
2119 | static netdev_features_t harmonize_features(struct sk_buff *skb, | 2134 | static netdev_features_t harmonize_features(struct sk_buff *skb, |
2120 | __be16 protocol, netdev_features_t features) | 2135 | __be16 protocol, netdev_features_t features) |
2121 | { | 2136 | { |
2122 | if (!can_checksum_protocol(features, protocol)) { | 2137 | if (skb->ip_summed != CHECKSUM_NONE && |
2138 | !can_checksum_protocol(features, protocol)) { | ||
2123 | features &= ~NETIF_F_ALL_CSUM; | 2139 | features &= ~NETIF_F_ALL_CSUM; |
2124 | features &= ~NETIF_F_SG; | 2140 | features &= ~NETIF_F_SG; |
2125 | } else if (illegal_highdma(skb->dev, skb)) { | 2141 | } else if (illegal_highdma(skb->dev, skb)) { |
@@ -2134,6 +2150,9 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2134 | __be16 protocol = skb->protocol; | 2150 | __be16 protocol = skb->protocol; |
2135 | netdev_features_t features = skb->dev->features; | 2151 | netdev_features_t features = skb->dev->features; |
2136 | 2152 | ||
2153 | if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) | ||
2154 | features &= ~NETIF_F_GSO_MASK; | ||
2155 | |||
2137 | if (protocol == htons(ETH_P_8021Q)) { | 2156 | if (protocol == htons(ETH_P_8021Q)) { |
2138 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2157 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
2139 | protocol = veh->h_vlan_encapsulated_proto; | 2158 | protocol = veh->h_vlan_encapsulated_proto; |
@@ -2629,15 +2648,16 @@ void __skb_get_rxhash(struct sk_buff *skb) | |||
2629 | if (!skb_flow_dissect(skb, &keys)) | 2648 | if (!skb_flow_dissect(skb, &keys)) |
2630 | return; | 2649 | return; |
2631 | 2650 | ||
2632 | if (keys.ports) { | 2651 | if (keys.ports) |
2633 | if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]) | ||
2634 | swap(keys.port16[0], keys.port16[1]); | ||
2635 | skb->l4_rxhash = 1; | 2652 | skb->l4_rxhash = 1; |
2636 | } | ||
2637 | 2653 | ||
2638 | /* get a consistent hash (same value on both flow directions) */ | 2654 | /* get a consistent hash (same value on both flow directions) */ |
2639 | if ((__force u32)keys.dst < (__force u32)keys.src) | 2655 | if (((__force u32)keys.dst < (__force u32)keys.src) || |
2656 | (((__force u32)keys.dst == (__force u32)keys.src) && | ||
2657 | ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) { | ||
2640 | swap(keys.dst, keys.src); | 2658 | swap(keys.dst, keys.src); |
2659 | swap(keys.port16[0], keys.port16[1]); | ||
2660 | } | ||
2641 | 2661 | ||
2642 | hash = jhash_3words((__force u32)keys.dst, | 2662 | hash = jhash_3words((__force u32)keys.dst, |
2643 | (__force u32)keys.src, | 2663 | (__force u32)keys.src, |
@@ -3303,7 +3323,7 @@ ncls: | |||
3303 | 3323 | ||
3304 | if (pt_prev) { | 3324 | if (pt_prev) { |
3305 | if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) | 3325 | if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) |
3306 | ret = -ENOMEM; | 3326 | goto drop; |
3307 | else | 3327 | else |
3308 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 3328 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
3309 | } else { | 3329 | } else { |
@@ -5726,6 +5746,7 @@ EXPORT_SYMBOL(netdev_refcnt_read); | |||
5726 | 5746 | ||
5727 | /** | 5747 | /** |
5728 | * netdev_wait_allrefs - wait until all references are gone. | 5748 | * netdev_wait_allrefs - wait until all references are gone. |
5749 | * @dev: target net_device | ||
5729 | * | 5750 | * |
5730 | * This is called when unregistering network devices. | 5751 | * This is called when unregistering network devices. |
5731 | * | 5752 | * |
@@ -5986,6 +6007,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
5986 | dev_net_set(dev, &init_net); | 6007 | dev_net_set(dev, &init_net); |
5987 | 6008 | ||
5988 | dev->gso_max_size = GSO_MAX_SIZE; | 6009 | dev->gso_max_size = GSO_MAX_SIZE; |
6010 | dev->gso_max_segs = GSO_MAX_SEGS; | ||
5989 | 6011 | ||
5990 | INIT_LIST_HEAD(&dev->napi_list); | 6012 | INIT_LIST_HEAD(&dev->napi_list); |
5991 | INIT_LIST_HEAD(&dev->unreg_list); | 6013 | INIT_LIST_HEAD(&dev->unreg_list); |