diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-08-30 18:30:38 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-08-30 18:30:38 -0400 |
commit | 0a7d5f8ce960e74fa22986bda4af488539796e49 (patch) | |
tree | e29ad17808a5c3410518e22dae8dfe94801b59f3 /net/core/dev.c | |
parent | 0165508c80a2b5d5268d9c5dfa9b30c534a33693 (diff) | |
parent | dc709bd190c130b299ac19d596594256265c042a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 78 |
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 | */ |
637 | int dev_valid_name(const char *name) | 639 | int 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 | |||
1197 | out_set_summed: | ||
1184 | skb->ip_summed = CHECKSUM_NONE; | 1198 | skb->ip_summed = CHECKSUM_NONE; |
1185 | out: | 1199 | out: |
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 | } |
1623 | keep: | ||
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 | /** |