aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-07-09 18:50:41 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-09 18:50:41 -0400
commit09075ef0fd585fb093bb9a6cd1240272114f89cf (patch)
treec01d2cc260a18df73f785bea4de1c1cfbcbbd16f /net/ipv4
parentc87fed1546bd00b42ee75f26c6b45393e4bf7559 (diff)
parent1b30dd359ebec22d035e8b145751319f63772ca1 (diff)
Merge commit master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 of HEAD
* HEAD: [AX.25]: Use kzalloc [ATM] net/atm/clip.c: fix PROC_FS=n compile [PKT_SCHED]: act_api: Fix module leak while flushing actions [NET]: Fix IPv4/DECnet routing rule dumping [NET] gso: Fix up GSO packets with broken checksums [NET] gso: Add skb_is_gso [IRDA]: fix drivers/net/irda/ali-ircc.c:ali_ircc_init() [ATM]: fix possible recursive locking in skb_migrate() [ATM]: Typo in drivers/atm/Kconfig... [TG3]: add amd8131 to "write reorder" chipsets [NET]: Fix network device interface printk message priority
Diffstat (limited to 'net/ipv4')
-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
5 files changed, 59 insertions, 5 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 318d4674fa..c84a32070f 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 6c642d11d4..773b12ba4e 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 ca0e714613..7c9f9a6421 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 5a886e6efb..a891133f00 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 193363e229..d16f863cf6 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);