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.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index f91abf800161..89e33a5d4d93 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1055,6 +1055,8 @@ rollback:
1055 */ 1055 */
1056int dev_set_alias(struct net_device *dev, const char *alias, size_t len) 1056int 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
1645static 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)
2119static netdev_features_t harmonize_features(struct sk_buff *skb, 2134static 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)) {
@@ -2632,15 +2648,16 @@ void __skb_get_rxhash(struct sk_buff *skb)
2632 if (!skb_flow_dissect(skb, &keys)) 2648 if (!skb_flow_dissect(skb, &keys))
2633 return; 2649 return;
2634 2650
2635 if (keys.ports) { 2651 if (keys.ports)
2636 if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0])
2637 swap(keys.port16[0], keys.port16[1]);
2638 skb->l4_rxhash = 1; 2652 skb->l4_rxhash = 1;
2639 }
2640 2653
2641 /* get a consistent hash (same value on both flow directions) */ 2654 /* get a consistent hash (same value on both flow directions) */
2642 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]))) {
2643 swap(keys.dst, keys.src); 2658 swap(keys.dst, keys.src);
2659 swap(keys.port16[0], keys.port16[1]);
2660 }
2644 2661
2645 hash = jhash_3words((__force u32)keys.dst, 2662 hash = jhash_3words((__force u32)keys.dst,
2646 (__force u32)keys.src, 2663 (__force u32)keys.src,
@@ -3306,7 +3323,7 @@ ncls:
3306 3323
3307 if (pt_prev) { 3324 if (pt_prev) {
3308 if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) 3325 if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
3309 ret = -ENOMEM; 3326 goto drop;
3310 else 3327 else
3311 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); 3328 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
3312 } else { 3329 } else {
@@ -5729,6 +5746,7 @@ EXPORT_SYMBOL(netdev_refcnt_read);
5729 5746
5730/** 5747/**
5731 * netdev_wait_allrefs - wait until all references are gone. 5748 * netdev_wait_allrefs - wait until all references are gone.
5749 * @dev: target net_device
5732 * 5750 *
5733 * This is called when unregistering network devices. 5751 * This is called when unregistering network devices.
5734 * 5752 *