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.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 066a60a75280..d4a1ec3bded5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -116,6 +116,7 @@
116#include <linux/audit.h> 116#include <linux/audit.h>
117#include <linux/dmaengine.h> 117#include <linux/dmaengine.h>
118#include <linux/err.h> 118#include <linux/err.h>
119#include <linux/ctype.h>
119 120
120/* 121/*
121 * The list of packet types we will receive (as opposed to discard) 122 * The list of packet types we will receive (as opposed to discard)
@@ -632,14 +633,22 @@ struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mas
632 * @name: name string 633 * @name: name string
633 * 634 *
634 * Network device names need to be valid file names to 635 * Network device names need to be valid file names to
635 * to allow sysfs to work 636 * to allow sysfs to work. We also disallow any kind of
637 * whitespace.
636 */ 638 */
637int dev_valid_name(const char *name) 639int dev_valid_name(const char *name)
638{ 640{
639 return !(*name == '\0' 641 if (*name == '\0')
640 || !strcmp(name, ".") 642 return 0;
641 || !strcmp(name, "..") 643 if (!strcmp(name, ".") || !strcmp(name, ".."))
642 || strchr(name, '/')); 644 return 0;
645
646 while (*name) {
647 if (*name == '/' || isspace(*name))
648 return 0;
649 name++;
650 }
651 return 1;
643} 652}
644 653
645/** 654/**
@@ -1162,9 +1171,12 @@ int skb_checksum_help(struct sk_buff *skb, int inward)
1162 unsigned int csum; 1171 unsigned int csum;
1163 int ret = 0, offset = skb->h.raw - skb->data; 1172 int ret = 0, offset = skb->h.raw - skb->data;
1164 1173
1165 if (inward) { 1174 if (inward)
1166 skb->ip_summed = CHECKSUM_NONE; 1175 goto out_set_summed;
1167 goto out; 1176
1177 if (unlikely(skb_shinfo(skb)->gso_size)) {
1178 /* Let GSO fix up the checksum. */
1179 goto out_set_summed;
1168 } 1180 }
1169 1181
1170 if (skb_cloned(skb)) { 1182 if (skb_cloned(skb)) {
@@ -1181,6 +1193,8 @@ int skb_checksum_help(struct sk_buff *skb, int inward)
1181 BUG_ON(skb->csum + 2 > offset); 1193 BUG_ON(skb->csum + 2 > offset);
1182 1194
1183 *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum); 1195 *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
1196
1197out_set_summed:
1184 skb->ip_summed = CHECKSUM_NONE; 1198 skb->ip_summed = CHECKSUM_NONE;
1185out: 1199out:
1186 return ret; 1200 return ret;
@@ -1201,17 +1215,30 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
1201 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 1215 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
1202 struct packet_type *ptype; 1216 struct packet_type *ptype;
1203 int type = skb->protocol; 1217 int type = skb->protocol;
1218 int err;
1204 1219
1205 BUG_ON(skb_shinfo(skb)->frag_list); 1220 BUG_ON(skb_shinfo(skb)->frag_list);
1206 BUG_ON(skb->ip_summed != CHECKSUM_HW);
1207 1221
1208 skb->mac.raw = skb->data; 1222 skb->mac.raw = skb->data;
1209 skb->mac_len = skb->nh.raw - skb->data; 1223 skb->mac_len = skb->nh.raw - skb->data;
1210 __skb_pull(skb, skb->mac_len); 1224 __skb_pull(skb, skb->mac_len);
1211 1225
1226 if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
1227 if (skb_header_cloned(skb) &&
1228 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
1229 return ERR_PTR(err);
1230 }
1231
1212 rcu_read_lock(); 1232 rcu_read_lock();
1213 list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { 1233 list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
1214 if (ptype->type == type && !ptype->dev && ptype->gso_segment) { 1234 if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
1235 if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
1236 err = ptype->gso_send_check(skb);
1237 segs = ERR_PTR(err);
1238 if (err || skb_gso_ok(skb, features))
1239 break;
1240 __skb_push(skb, skb->data - skb->nh.raw);
1241 }
1215 segs = ptype->gso_segment(skb, features); 1242 segs = ptype->gso_segment(skb, features);
1216 break; 1243 break;
1217 } 1244 }
@@ -1601,26 +1628,10 @@ static inline struct net_device *skb_bond(struct sk_buff *skb)
1601 struct net_device *dev = skb->dev; 1628 struct net_device *dev = skb->dev;
1602 1629
1603 if (dev->master) { 1630 if (dev->master) {
1604 /* 1631 if (skb_bond_should_drop(skb)) {
1605 * On bonding slaves other than the currently active
1606 * slave, suppress duplicates except for 802.3ad
1607 * ETH_P_SLOW and alb non-mcast/bcast.
1608 */
1609 if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
1610 if (dev->master->priv_flags & IFF_MASTER_ALB) {
1611 if (skb->pkt_type != PACKET_BROADCAST &&
1612 skb->pkt_type != PACKET_MULTICAST)
1613 goto keep;
1614 }
1615
1616 if (dev->master->priv_flags & IFF_MASTER_8023AD &&
1617 skb->protocol == __constant_htons(ETH_P_SLOW))
1618 goto keep;
1619
1620 kfree_skb(skb); 1632 kfree_skb(skb);
1621 return NULL; 1633 return NULL;
1622 } 1634 }
1623keep:
1624 skb->dev = dev->master; 1635 skb->dev = dev->master;
1625 } 1636 }
1626 1637
@@ -1727,7 +1738,7 @@ static int ing_filter(struct sk_buff *skb)
1727 if (dev->qdisc_ingress) { 1738 if (dev->qdisc_ingress) {
1728 __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd); 1739 __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
1729 if (MAX_RED_LOOP < ttl++) { 1740 if (MAX_RED_LOOP < ttl++) {
1730 printk("Redir loop detected Dropping packet (%s->%s)\n", 1741 printk(KERN_WARNING "Redir loop detected Dropping packet (%s->%s)\n",
1731 skb->input_dev->name, skb->dev->name); 1742 skb->input_dev->name, skb->dev->name);
1732 return TC_ACT_SHOT; 1743 return TC_ACT_SHOT;
1733 } 1744 }
@@ -2922,7 +2933,7 @@ int register_netdevice(struct net_device *dev)
2922 /* Fix illegal SG+CSUM combinations. */ 2933 /* Fix illegal SG+CSUM combinations. */
2923 if ((dev->features & NETIF_F_SG) && 2934 if ((dev->features & NETIF_F_SG) &&
2924 !(dev->features & NETIF_F_ALL_CSUM)) { 2935 !(dev->features & NETIF_F_ALL_CSUM)) {
2925 printk("%s: Dropping NETIF_F_SG since no checksum feature.\n", 2936 printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n",
2926 dev->name); 2937 dev->name);
2927 dev->features &= ~NETIF_F_SG; 2938 dev->features &= ~NETIF_F_SG;
2928 } 2939 }
@@ -2930,7 +2941,7 @@ int register_netdevice(struct net_device *dev)
2930 /* TSO requires that SG is present as well. */ 2941 /* TSO requires that SG is present as well. */
2931 if ((dev->features & NETIF_F_TSO) && 2942 if ((dev->features & NETIF_F_TSO) &&
2932 !(dev->features & NETIF_F_SG)) { 2943 !(dev->features & NETIF_F_SG)) {
2933 printk("%s: Dropping NETIF_F_TSO since no SG feature.\n", 2944 printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no SG feature.\n",
2934 dev->name); 2945 dev->name);
2935 dev->features &= ~NETIF_F_TSO; 2946 dev->features &= ~NETIF_F_TSO;
2936 } 2947 }
@@ -3401,12 +3412,9 @@ static void net_dma_rebalance(void)
3401 unsigned int cpu, i, n; 3412 unsigned int cpu, i, n;
3402 struct dma_chan *chan; 3413 struct dma_chan *chan;
3403 3414
3404 lock_cpu_hotplug();
3405
3406 if (net_dma_count == 0) { 3415 if (net_dma_count == 0) {
3407 for_each_online_cpu(cpu) 3416 for_each_online_cpu(cpu)
3408 rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL); 3417 rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL);
3409 unlock_cpu_hotplug();
3410 return; 3418 return;
3411 } 3419 }
3412 3420
@@ -3419,15 +3427,13 @@ static void net_dma_rebalance(void)
3419 + (i < (num_online_cpus() % net_dma_count) ? 1 : 0)); 3427 + (i < (num_online_cpus() % net_dma_count) ? 1 : 0));
3420 3428
3421 while(n) { 3429 while(n) {
3422 per_cpu(softnet_data.net_dma, cpu) = chan; 3430 per_cpu(softnet_data, cpu).net_dma = chan;
3423 cpu = next_cpu(cpu, cpu_online_map); 3431 cpu = next_cpu(cpu, cpu_online_map);
3424 n--; 3432 n--;
3425 } 3433 }
3426 i++; 3434 i++;
3427 } 3435 }
3428 rcu_read_unlock(); 3436 rcu_read_unlock();
3429
3430 unlock_cpu_hotplug();
3431} 3437}
3432 3438
3433/** 3439/**