aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/atm/clip.c13
-rw-r--r--net/atm/ipcommon.c17
-rw-r--r--net/ax25/af_ax25.c3
-rw-r--r--net/ax25/ax25_dev.c4
-rw-r--r--net/bridge/br_forward.c2
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/core/dev.c42
-rw-r--r--net/decnet/dn_rules.c3
-rw-r--r--net/ipv4/af_inet.c36
-rw-r--r--net/ipv4/fib_rules.c4
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/tcp_ipv4.c18
-rw-r--r--net/ipv4/xfrm4_output.c2
-rw-r--r--net/ipv6/ip6_output.c4
-rw-r--r--net/ipv6/ipv6_sockglue.c89
-rw-r--r--net/ipv6/tcp_ipv6.c19
-rw-r--r--net/ipv6/xfrm6_output.c2
-rw-r--r--net/netrom/af_netrom.c4
-rw-r--r--net/rose/af_rose.c3
-rw-r--r--net/sched/act_api.c2
20 files changed, 206 insertions, 67 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 121bf6f49148..2e62105d91bd 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -962,7 +962,6 @@ static struct file_operations arp_seq_fops = {
962 962
963static int __init atm_clip_init(void) 963static int __init atm_clip_init(void)
964{ 964{
965 struct proc_dir_entry *p;
966 neigh_table_init_no_netlink(&clip_tbl); 965 neigh_table_init_no_netlink(&clip_tbl);
967 966
968 clip_tbl_hook = &clip_tbl; 967 clip_tbl_hook = &clip_tbl;
@@ -972,9 +971,15 @@ static int __init atm_clip_init(void)
972 971
973 setup_timer(&idle_timer, idle_timer_check, 0); 972 setup_timer(&idle_timer, idle_timer_check, 0);
974 973
975 p = create_proc_entry("arp", S_IRUGO, atm_proc_root); 974#ifdef CONFIG_PROC_FS
976 if (p) 975 {
977 p->proc_fops = &arp_seq_fops; 976 struct proc_dir_entry *p;
977
978 p = create_proc_entry("arp", S_IRUGO, atm_proc_root);
979 if (p)
980 p->proc_fops = &arp_seq_fops;
981 }
982#endif
978 983
979 return 0; 984 return 0;
980} 985}
diff --git a/net/atm/ipcommon.c b/net/atm/ipcommon.c
index 4b1faca5013f..1d3de42fada0 100644
--- a/net/atm/ipcommon.c
+++ b/net/atm/ipcommon.c
@@ -25,22 +25,27 @@
25/* 25/*
26 * skb_migrate appends the list at "from" to "to", emptying "from" in the 26 * skb_migrate appends the list at "from" to "to", emptying "from" in the
27 * process. skb_migrate is atomic with respect to all other skb operations on 27 * process. skb_migrate is atomic with respect to all other skb operations on
28 * "from" and "to". Note that it locks both lists at the same time, so beware 28 * "from" and "to". Note that it locks both lists at the same time, so to deal
29 * of potential deadlocks. 29 * with the lock ordering, the locks are taken in address order.
30 * 30 *
31 * This function should live in skbuff.c or skbuff.h. 31 * This function should live in skbuff.c or skbuff.h.
32 */ 32 */
33 33
34 34
35void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to) 35void skb_migrate(struct sk_buff_head *from, struct sk_buff_head *to)
36{ 36{
37 unsigned long flags; 37 unsigned long flags;
38 struct sk_buff *skb_from = (struct sk_buff *) from; 38 struct sk_buff *skb_from = (struct sk_buff *) from;
39 struct sk_buff *skb_to = (struct sk_buff *) to; 39 struct sk_buff *skb_to = (struct sk_buff *) to;
40 struct sk_buff *prev; 40 struct sk_buff *prev;
41 41
42 spin_lock_irqsave(&from->lock,flags); 42 if ((unsigned long) from < (unsigned long) to) {
43 spin_lock(&to->lock); 43 spin_lock_irqsave(&from->lock, flags);
44 spin_lock_nested(&to->lock, SINGLE_DEPTH_NESTING);
45 } else {
46 spin_lock_irqsave(&to->lock, flags);
47 spin_lock_nested(&from->lock, SINGLE_DEPTH_NESTING);
48 }
44 prev = from->prev; 49 prev = from->prev;
45 from->next->prev = to->prev; 50 from->next->prev = to->prev;
46 prev->next = skb_to; 51 prev->next = skb_to;
@@ -51,7 +56,7 @@ void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to)
51 from->prev = skb_from; 56 from->prev = skb_from;
52 from->next = skb_from; 57 from->next = skb_from;
53 from->qlen = 0; 58 from->qlen = 0;
54 spin_unlock_irqrestore(&from->lock,flags); 59 spin_unlock_irqrestore(&from->lock, flags);
55} 60}
56 61
57 62
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 10a3c0aa8398..f12be2acf9bc 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -486,10 +486,9 @@ ax25_cb *ax25_create_cb(void)
486{ 486{
487 ax25_cb *ax25; 487 ax25_cb *ax25;
488 488
489 if ((ax25 = kmalloc(sizeof(*ax25), GFP_ATOMIC)) == NULL) 489 if ((ax25 = kzalloc(sizeof(*ax25), GFP_ATOMIC)) == NULL)
490 return NULL; 490 return NULL;
491 491
492 memset(ax25, 0x00, sizeof(*ax25));
493 atomic_set(&ax25->refcount, 1); 492 atomic_set(&ax25->refcount, 1);
494 493
495 skb_queue_head_init(&ax25->write_queue); 494 skb_queue_head_init(&ax25->write_queue);
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
index 47e6e790bd67..b787678220ff 100644
--- a/net/ax25/ax25_dev.c
+++ b/net/ax25/ax25_dev.c
@@ -55,15 +55,13 @@ void ax25_dev_device_up(struct net_device *dev)
55{ 55{
56 ax25_dev *ax25_dev; 56 ax25_dev *ax25_dev;
57 57
58 if ((ax25_dev = kmalloc(sizeof(*ax25_dev), GFP_ATOMIC)) == NULL) { 58 if ((ax25_dev = kzalloc(sizeof(*ax25_dev), GFP_ATOMIC)) == NULL) {
59 printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n"); 59 printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n");
60 return; 60 return;
61 } 61 }
62 62
63 ax25_unregister_sysctl(); 63 ax25_unregister_sysctl();
64 64
65 memset(ax25_dev, 0x00, sizeof(*ax25_dev));
66
67 dev->ax25_ptr = ax25_dev; 65 dev->ax25_ptr = ax25_dev;
68 ax25_dev->dev = dev; 66 ax25_dev->dev = dev;
69 dev_hold(dev); 67 dev_hold(dev);
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 8be9f2123e54..6ccd32b30809 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -35,7 +35,7 @@ static inline unsigned packet_length(const struct sk_buff *skb)
35int br_dev_queue_push_xmit(struct sk_buff *skb) 35int br_dev_queue_push_xmit(struct sk_buff *skb)
36{ 36{
37 /* drop mtu oversized packets except gso */ 37 /* drop mtu oversized packets except gso */
38 if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->gso_size) 38 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
39 kfree_skb(skb); 39 kfree_skb(skb);
40 else { 40 else {
41#ifdef CONFIG_BRIDGE_NETFILTER 41#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 8298a5179aef..cbc8a389a0a8 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -761,7 +761,7 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb)
761{ 761{
762 if (skb->protocol == htons(ETH_P_IP) && 762 if (skb->protocol == htons(ETH_P_IP) &&
763 skb->len > skb->dev->mtu && 763 skb->len > skb->dev->mtu &&
764 !skb_shinfo(skb)->gso_size) 764 !skb_is_gso(skb))
765 return ip_fragment(skb, br_dev_queue_push_xmit); 765 return ip_fragment(skb, br_dev_queue_push_xmit);
766 else 766 else
767 return br_dev_queue_push_xmit(skb); 767 return br_dev_queue_push_xmit(skb);
diff --git a/net/core/dev.c b/net/core/dev.c
index 066a60a75280..4d2b5167d7f5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1162,9 +1162,17 @@ int skb_checksum_help(struct sk_buff *skb, int inward)
1162 unsigned int csum; 1162 unsigned int csum;
1163 int ret = 0, offset = skb->h.raw - skb->data; 1163 int ret = 0, offset = skb->h.raw - skb->data;
1164 1164
1165 if (inward) { 1165 if (inward)
1166 skb->ip_summed = CHECKSUM_NONE; 1166 goto out_set_summed;
1167 goto out; 1167
1168 if (unlikely(skb_shinfo(skb)->gso_size)) {
1169 static int warned;
1170
1171 WARN_ON(!warned);
1172 warned = 1;
1173
1174 /* Let GSO fix up the checksum. */
1175 goto out_set_summed;
1168 } 1176 }
1169 1177
1170 if (skb_cloned(skb)) { 1178 if (skb_cloned(skb)) {
@@ -1181,6 +1189,8 @@ int skb_checksum_help(struct sk_buff *skb, int inward)
1181 BUG_ON(skb->csum + 2 > offset); 1189 BUG_ON(skb->csum + 2 > offset);
1182 1190
1183 *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum); 1191 *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
1192
1193out_set_summed:
1184 skb->ip_summed = CHECKSUM_NONE; 1194 skb->ip_summed = CHECKSUM_NONE;
1185out: 1195out:
1186 return ret; 1196 return ret;
@@ -1201,17 +1211,35 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
1201 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 1211 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
1202 struct packet_type *ptype; 1212 struct packet_type *ptype;
1203 int type = skb->protocol; 1213 int type = skb->protocol;
1214 int err;
1204 1215
1205 BUG_ON(skb_shinfo(skb)->frag_list); 1216 BUG_ON(skb_shinfo(skb)->frag_list);
1206 BUG_ON(skb->ip_summed != CHECKSUM_HW);
1207 1217
1208 skb->mac.raw = skb->data; 1218 skb->mac.raw = skb->data;
1209 skb->mac_len = skb->nh.raw - skb->data; 1219 skb->mac_len = skb->nh.raw - skb->data;
1210 __skb_pull(skb, skb->mac_len); 1220 __skb_pull(skb, skb->mac_len);
1211 1221
1222 if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
1223 static int warned;
1224
1225 WARN_ON(!warned);
1226 warned = 1;
1227
1228 if (skb_header_cloned(skb) &&
1229 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
1230 return ERR_PTR(err);
1231 }
1232
1212 rcu_read_lock(); 1233 rcu_read_lock();
1213 list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { 1234 list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
1214 if (ptype->type == type && !ptype->dev && ptype->gso_segment) { 1235 if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
1236 if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
1237 err = ptype->gso_send_check(skb);
1238 segs = ERR_PTR(err);
1239 if (err || skb_gso_ok(skb, features))
1240 break;
1241 __skb_push(skb, skb->data - skb->nh.raw);
1242 }
1215 segs = ptype->gso_segment(skb, features); 1243 segs = ptype->gso_segment(skb, features);
1216 break; 1244 break;
1217 } 1245 }
@@ -1727,7 +1755,7 @@ static int ing_filter(struct sk_buff *skb)
1727 if (dev->qdisc_ingress) { 1755 if (dev->qdisc_ingress) {
1728 __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd); 1756 __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
1729 if (MAX_RED_LOOP < ttl++) { 1757 if (MAX_RED_LOOP < ttl++) {
1730 printk("Redir loop detected Dropping packet (%s->%s)\n", 1758 printk(KERN_WARNING "Redir loop detected Dropping packet (%s->%s)\n",
1731 skb->input_dev->name, skb->dev->name); 1759 skb->input_dev->name, skb->dev->name);
1732 return TC_ACT_SHOT; 1760 return TC_ACT_SHOT;
1733 } 1761 }
@@ -2922,7 +2950,7 @@ int register_netdevice(struct net_device *dev)
2922 /* Fix illegal SG+CSUM combinations. */ 2950 /* Fix illegal SG+CSUM combinations. */
2923 if ((dev->features & NETIF_F_SG) && 2951 if ((dev->features & NETIF_F_SG) &&
2924 !(dev->features & NETIF_F_ALL_CSUM)) { 2952 !(dev->features & NETIF_F_ALL_CSUM)) {
2925 printk("%s: Dropping NETIF_F_SG since no checksum feature.\n", 2953 printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n",
2926 dev->name); 2954 dev->name);
2927 dev->features &= ~NETIF_F_SG; 2955 dev->features &= ~NETIF_F_SG;
2928 } 2956 }
@@ -2930,7 +2958,7 @@ int register_netdevice(struct net_device *dev)
2930 /* TSO requires that SG is present as well. */ 2958 /* TSO requires that SG is present as well. */
2931 if ((dev->features & NETIF_F_TSO) && 2959 if ((dev->features & NETIF_F_TSO) &&
2932 !(dev->features & NETIF_F_SG)) { 2960 !(dev->features & NETIF_F_SG)) {
2933 printk("%s: Dropping NETIF_F_TSO since no SG feature.\n", 2961 printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no SG feature.\n",
2934 dev->name); 2962 dev->name);
2935 dev->features &= ~NETIF_F_TSO; 2963 dev->features &= ~NETIF_F_TSO;
2936 } 2964 }
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 06e785fe5757..22f321d9bf9d 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -399,9 +399,10 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
399 rcu_read_lock(); 399 rcu_read_lock();
400 hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) { 400 hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
401 if (idx < s_idx) 401 if (idx < s_idx)
402 continue; 402 goto next;
403 if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0) 403 if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
404 break; 404 break;
405next:
405 idx++; 406 idx++;
406 } 407 }
407 rcu_read_unlock(); 408 rcu_read_unlock();
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 318d4674faa1..c84a32070f8d 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1097,6 +1097,40 @@ int inet_sk_rebuild_header(struct sock *sk)
1097 1097
1098EXPORT_SYMBOL(inet_sk_rebuild_header); 1098EXPORT_SYMBOL(inet_sk_rebuild_header);
1099 1099
1100static int inet_gso_send_check(struct sk_buff *skb)
1101{
1102 struct iphdr *iph;
1103 struct net_protocol *ops;
1104 int proto;
1105 int ihl;
1106 int err = -EINVAL;
1107
1108 if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
1109 goto out;
1110
1111 iph = skb->nh.iph;
1112 ihl = iph->ihl * 4;
1113 if (ihl < sizeof(*iph))
1114 goto out;
1115
1116 if (unlikely(!pskb_may_pull(skb, ihl)))
1117 goto out;
1118
1119 skb->h.raw = __skb_pull(skb, ihl);
1120 iph = skb->nh.iph;
1121 proto = iph->protocol & (MAX_INET_PROTOS - 1);
1122 err = -EPROTONOSUPPORT;
1123
1124 rcu_read_lock();
1125 ops = rcu_dereference(inet_protos[proto]);
1126 if (likely(ops && ops->gso_send_check))
1127 err = ops->gso_send_check(skb);
1128 rcu_read_unlock();
1129
1130out:
1131 return err;
1132}
1133
1100static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) 1134static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
1101{ 1135{
1102 struct sk_buff *segs = ERR_PTR(-EINVAL); 1136 struct sk_buff *segs = ERR_PTR(-EINVAL);
@@ -1162,6 +1196,7 @@ static struct net_protocol igmp_protocol = {
1162static struct net_protocol tcp_protocol = { 1196static struct net_protocol tcp_protocol = {
1163 .handler = tcp_v4_rcv, 1197 .handler = tcp_v4_rcv,
1164 .err_handler = tcp_v4_err, 1198 .err_handler = tcp_v4_err,
1199 .gso_send_check = tcp_v4_gso_send_check,
1165 .gso_segment = tcp_tso_segment, 1200 .gso_segment = tcp_tso_segment,
1166 .no_policy = 1, 1201 .no_policy = 1,
1167}; 1202};
@@ -1208,6 +1243,7 @@ static int ipv4_proc_init(void);
1208static struct packet_type ip_packet_type = { 1243static struct packet_type ip_packet_type = {
1209 .type = __constant_htons(ETH_P_IP), 1244 .type = __constant_htons(ETH_P_IP),
1210 .func = ip_rcv, 1245 .func = ip_rcv,
1246 .gso_send_check = inet_gso_send_check,
1211 .gso_segment = inet_gso_segment, 1247 .gso_segment = inet_gso_segment,
1212}; 1248};
1213 1249
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 6c642d11d4ca..773b12ba4e3c 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -457,13 +457,13 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
457 457
458 rcu_read_lock(); 458 rcu_read_lock();
459 hlist_for_each_entry(r, node, &fib_rules, hlist) { 459 hlist_for_each_entry(r, node, &fib_rules, hlist) {
460
461 if (idx < s_idx) 460 if (idx < s_idx)
462 continue; 461 goto next;
463 if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid, 462 if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid,
464 cb->nlh->nlmsg_seq, 463 cb->nlh->nlmsg_seq,
465 RTM_NEWRULE, NLM_F_MULTI) < 0) 464 RTM_NEWRULE, NLM_F_MULTI) < 0)
466 break; 465 break;
466next:
467 idx++; 467 idx++;
468 } 468 }
469 rcu_read_unlock(); 469 rcu_read_unlock();
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ca0e714613fb..7c9f9a6421b8 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -209,7 +209,7 @@ static inline int ip_finish_output(struct sk_buff *skb)
209 return dst_output(skb); 209 return dst_output(skb);
210 } 210 }
211#endif 211#endif
212 if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) 212 if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb))
213 return ip_fragment(skb, ip_finish_output2); 213 return ip_fragment(skb, ip_finish_output2);
214 else 214 else
215 return ip_finish_output2(skb); 215 return ip_finish_output2(skb);
@@ -1095,7 +1095,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1095 while (size > 0) { 1095 while (size > 0) {
1096 int i; 1096 int i;
1097 1097
1098 if (skb_shinfo(skb)->gso_size) 1098 if (skb_is_gso(skb))
1099 len = size; 1099 len = size;
1100 else { 1100 else {
1101 1101
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 5a886e6efbbe..a891133f00e4 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -496,6 +496,24 @@ void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
496 } 496 }
497} 497}
498 498
499int tcp_v4_gso_send_check(struct sk_buff *skb)
500{
501 struct iphdr *iph;
502 struct tcphdr *th;
503
504 if (!pskb_may_pull(skb, sizeof(*th)))
505 return -EINVAL;
506
507 iph = skb->nh.iph;
508 th = skb->h.th;
509
510 th->check = 0;
511 th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
512 skb->csum = offsetof(struct tcphdr, check);
513 skb->ip_summed = CHECKSUM_HW;
514 return 0;
515}
516
499/* 517/*
500 * This routine will send an RST to the other tcp. 518 * This routine will send an RST to the other tcp.
501 * 519 *
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 193363e22932..d16f863cf687 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -134,7 +134,7 @@ static int xfrm4_output_finish(struct sk_buff *skb)
134 } 134 }
135#endif 135#endif
136 136
137 if (!skb_shinfo(skb)->gso_size) 137 if (!skb_is_gso(skb))
138 return xfrm4_output_finish2(skb); 138 return xfrm4_output_finish2(skb);
139 139
140 skb->protocol = htons(ETH_P_IP); 140 skb->protocol = htons(ETH_P_IP);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 2c5b44575af0..3bc74ce78800 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *skb)
147 147
148int ip6_output(struct sk_buff *skb) 148int ip6_output(struct sk_buff *skb)
149{ 149{
150 if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) || 150 if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) ||
151 dst_allfrag(skb->dst)) 151 dst_allfrag(skb->dst))
152 return ip6_fragment(skb, ip6_output2); 152 return ip6_fragment(skb, ip6_output2);
153 else 153 else
@@ -229,7 +229,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
229 skb->priority = sk->sk_priority; 229 skb->priority = sk->sk_priority;
230 230
231 mtu = dst_mtu(dst); 231 mtu = dst_mtu(dst);
232 if ((skb->len <= mtu) || ipfragok || skb_shinfo(skb)->gso_size) { 232 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
233 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 233 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
234 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, 234 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
235 dst_output); 235 dst_output);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 0c17dec11c8d..43327264e69c 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -57,29 +57,11 @@
57 57
58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly; 58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly;
59 59
60static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features) 60static struct inet6_protocol *ipv6_gso_pull_exthdrs(struct sk_buff *skb,
61 int proto)
61{ 62{
62 struct sk_buff *segs = ERR_PTR(-EINVAL); 63 struct inet6_protocol *ops = NULL;
63 struct ipv6hdr *ipv6h;
64 struct inet6_protocol *ops;
65 int proto;
66 64
67 if (unlikely(skb_shinfo(skb)->gso_type &
68 ~(SKB_GSO_UDP |
69 SKB_GSO_DODGY |
70 SKB_GSO_TCP_ECN |
71 SKB_GSO_TCPV6 |
72 0)))
73 goto out;
74
75 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
76 goto out;
77
78 ipv6h = skb->nh.ipv6h;
79 proto = ipv6h->nexthdr;
80 __skb_pull(skb, sizeof(*ipv6h));
81
82 rcu_read_lock();
83 for (;;) { 65 for (;;) {
84 struct ipv6_opt_hdr *opth; 66 struct ipv6_opt_hdr *opth;
85 int len; 67 int len;
@@ -88,30 +70,80 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
88 ops = rcu_dereference(inet6_protos[proto]); 70 ops = rcu_dereference(inet6_protos[proto]);
89 71
90 if (unlikely(!ops)) 72 if (unlikely(!ops))
91 goto unlock; 73 break;
92 74
93 if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) 75 if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
94 break; 76 break;
95 } 77 }
96 78
97 if (unlikely(!pskb_may_pull(skb, 8))) 79 if (unlikely(!pskb_may_pull(skb, 8)))
98 goto unlock; 80 break;
99 81
100 opth = (void *)skb->data; 82 opth = (void *)skb->data;
101 len = opth->hdrlen * 8 + 8; 83 len = opth->hdrlen * 8 + 8;
102 84
103 if (unlikely(!pskb_may_pull(skb, len))) 85 if (unlikely(!pskb_may_pull(skb, len)))
104 goto unlock; 86 break;
105 87
106 proto = opth->nexthdr; 88 proto = opth->nexthdr;
107 __skb_pull(skb, len); 89 __skb_pull(skb, len);
108 } 90 }
109 91
110 skb->h.raw = skb->data; 92 return ops;
111 if (likely(ops->gso_segment)) 93}
112 segs = ops->gso_segment(skb, features); 94
95static int ipv6_gso_send_check(struct sk_buff *skb)
96{
97 struct ipv6hdr *ipv6h;
98 struct inet6_protocol *ops;
99 int err = -EINVAL;
100
101 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
102 goto out;
113 103
114unlock: 104 ipv6h = skb->nh.ipv6h;
105 __skb_pull(skb, sizeof(*ipv6h));
106 err = -EPROTONOSUPPORT;
107
108 rcu_read_lock();
109 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
110 if (likely(ops && ops->gso_send_check)) {
111 skb->h.raw = skb->data;
112 err = ops->gso_send_check(skb);
113 }
114 rcu_read_unlock();
115
116out:
117 return err;
118}
119
120static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
121{
122 struct sk_buff *segs = ERR_PTR(-EINVAL);
123 struct ipv6hdr *ipv6h;
124 struct inet6_protocol *ops;
125
126 if (unlikely(skb_shinfo(skb)->gso_type &
127 ~(SKB_GSO_UDP |
128 SKB_GSO_DODGY |
129 SKB_GSO_TCP_ECN |
130 SKB_GSO_TCPV6 |
131 0)))
132 goto out;
133
134 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
135 goto out;
136
137 ipv6h = skb->nh.ipv6h;
138 __skb_pull(skb, sizeof(*ipv6h));
139 segs = ERR_PTR(-EPROTONOSUPPORT);
140
141 rcu_read_lock();
142 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
143 if (likely(ops && ops->gso_segment)) {
144 skb->h.raw = skb->data;
145 segs = ops->gso_segment(skb, features);
146 }
115 rcu_read_unlock(); 147 rcu_read_unlock();
116 148
117 if (unlikely(IS_ERR(segs))) 149 if (unlikely(IS_ERR(segs)))
@@ -130,6 +162,7 @@ out:
130static struct packet_type ipv6_packet_type = { 162static struct packet_type ipv6_packet_type = {
131 .type = __constant_htons(ETH_P_IPV6), 163 .type = __constant_htons(ETH_P_IPV6),
132 .func = ipv6_rcv, 164 .func = ipv6_rcv,
165 .gso_send_check = ipv6_gso_send_check,
133 .gso_segment = ipv6_gso_segment, 166 .gso_segment = ipv6_gso_segment,
134}; 167};
135 168
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5bdcb9002cf7..923989d0520d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -552,6 +552,24 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
552 } 552 }
553} 553}
554 554
555static int tcp_v6_gso_send_check(struct sk_buff *skb)
556{
557 struct ipv6hdr *ipv6h;
558 struct tcphdr *th;
559
560 if (!pskb_may_pull(skb, sizeof(*th)))
561 return -EINVAL;
562
563 ipv6h = skb->nh.ipv6h;
564 th = skb->h.th;
565
566 th->check = 0;
567 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
568 IPPROTO_TCP, 0);
569 skb->csum = offsetof(struct tcphdr, check);
570 skb->ip_summed = CHECKSUM_HW;
571 return 0;
572}
555 573
556static void tcp_v6_send_reset(struct sk_buff *skb) 574static void tcp_v6_send_reset(struct sk_buff *skb)
557{ 575{
@@ -1603,6 +1621,7 @@ struct proto tcpv6_prot = {
1603static struct inet6_protocol tcpv6_protocol = { 1621static struct inet6_protocol tcpv6_protocol = {
1604 .handler = tcp_v6_rcv, 1622 .handler = tcp_v6_rcv,
1605 .err_handler = tcp_v6_err, 1623 .err_handler = tcp_v6_err,
1624 .gso_send_check = tcp_v6_gso_send_check,
1606 .gso_segment = tcp_tso_segment, 1625 .gso_segment = tcp_tso_segment,
1607 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 1626 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1608}; 1627};
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 48fccb1eca08..0eea60ea9ebc 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -122,7 +122,7 @@ static int xfrm6_output_finish(struct sk_buff *skb)
122{ 122{
123 struct sk_buff *segs; 123 struct sk_buff *segs;
124 124
125 if (!skb_shinfo(skb)->gso_size) 125 if (!skb_is_gso(skb))
126 return xfrm6_output_finish2(skb); 126 return xfrm6_output_finish2(skb);
127 127
128 skb->protocol = htons(ETH_P_IP); 128 skb->protocol = htons(ETH_P_IP);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 389a4119e1b4..ecc796878f38 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1382,14 +1382,12 @@ static int __init nr_proto_init(void)
1382 return -1; 1382 return -1;
1383 } 1383 }
1384 1384
1385 dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL); 1385 dev_nr = kzalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL);
1386 if (dev_nr == NULL) { 1386 if (dev_nr == NULL) {
1387 printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n"); 1387 printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n");
1388 return -1; 1388 return -1;
1389 } 1389 }
1390 1390
1391 memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device *));
1392
1393 for (i = 0; i < nr_ndevs; i++) { 1391 for (i = 0; i < nr_ndevs; i++) {
1394 char name[IFNAMSIZ]; 1392 char name[IFNAMSIZ];
1395 struct net_device *dev; 1393 struct net_device *dev;
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index d0a67bb31363..c115295ab431 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1490,14 +1490,13 @@ static int __init rose_proto_init(void)
1490 1490
1491 rose_callsign = null_ax25_address; 1491 rose_callsign = null_ax25_address;
1492 1492
1493 dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL); 1493 dev_rose = kzalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL);
1494 if (dev_rose == NULL) { 1494 if (dev_rose == NULL) {
1495 printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); 1495 printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n");
1496 rc = -ENOMEM; 1496 rc = -ENOMEM;
1497 goto out_proto_unregister; 1497 goto out_proto_unregister;
1498 } 1498 }
1499 1499
1500 memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device*));
1501 for (i = 0; i < rose_ndevs; i++) { 1500 for (i = 0; i < rose_ndevs; i++) {
1502 struct net_device *dev; 1501 struct net_device *dev;
1503 char name[IFNAMSIZ]; 1502 char name[IFNAMSIZ];
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 599423cc9d0d..0972247a839c 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -602,8 +602,8 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
602 return err; 602 return err;
603 603
604rtattr_failure: 604rtattr_failure:
605 module_put(a->ops->owner);
606nlmsg_failure: 605nlmsg_failure:
606 module_put(a->ops->owner);
607err_out: 607err_out:
608 kfree_skb(skb); 608 kfree_skb(skb);
609 kfree(a); 609 kfree(a);