diff options
author | Patrick McHardy <kaber@trash.net> | 2010-05-10 12:39:28 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-05-10 12:39:28 -0400 |
commit | 1e4b1057121bc756b91758a434b504d2010f6088 (patch) | |
tree | b016cf2c728289c7e36d9e4e488f30ab0bd0ae6e /net/ipv6/ip6_output.c | |
parent | 3b254c54ec46eb022cb26ee6ab37fae23f5f7d6a (diff) | |
parent | 3ee943728fff536edaf8f59faa58aaa1aa7366e3 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
net/bridge/br_device.c
net/bridge/br_forward.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7f12e30cfa73..5173acaeb501 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -92,7 +92,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
92 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 92 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
93 | WARN_ON(!skb_dst(newskb)); | 93 | WARN_ON(!skb_dst(newskb)); |
94 | 94 | ||
95 | netif_rx(newskb); | 95 | netif_rx_ni(newskb); |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
@@ -216,8 +216,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
216 | } | 216 | } |
217 | kfree_skb(skb); | 217 | kfree_skb(skb); |
218 | skb = skb2; | 218 | skb = skb2; |
219 | if (sk) | 219 | skb_set_owner_w(skb, sk); |
220 | skb_set_owner_w(skb, sk); | ||
221 | } | 220 | } |
222 | if (opt->opt_flen) | 221 | if (opt->opt_flen) |
223 | ipv6_push_frag_opts(skb, opt, &proto); | 222 | ipv6_push_frag_opts(skb, opt, &proto); |
@@ -623,7 +622,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
623 | /* We must not fragment if the socket is set to force MTU discovery | 622 | /* We must not fragment if the socket is set to force MTU discovery |
624 | * or if the skb it not generated by a local socket. | 623 | * or if the skb it not generated by a local socket. |
625 | */ | 624 | */ |
626 | if (!skb->local_df) { | 625 | if (!skb->local_df && skb->len > mtu) { |
627 | skb->dev = skb_dst(skb)->dev; | 626 | skb->dev = skb_dst(skb)->dev; |
628 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 627 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
629 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 628 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
@@ -1103,7 +1102,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1103 | int offset, int len, int odd, struct sk_buff *skb), | 1102 | int offset, int len, int odd, struct sk_buff *skb), |
1104 | void *from, int length, int transhdrlen, | 1103 | void *from, int length, int transhdrlen, |
1105 | int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, | 1104 | int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, |
1106 | struct rt6_info *rt, unsigned int flags) | 1105 | struct rt6_info *rt, unsigned int flags, int dontfrag) |
1107 | { | 1106 | { |
1108 | struct inet_sock *inet = inet_sk(sk); | 1107 | struct inet_sock *inet = inet_sk(sk); |
1109 | struct ipv6_pinfo *np = inet6_sk(sk); | 1108 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -1217,15 +1216,23 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1217 | */ | 1216 | */ |
1218 | 1217 | ||
1219 | inet->cork.length += length; | 1218 | inet->cork.length += length; |
1220 | if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && | 1219 | if (length > mtu) { |
1221 | (rt->u.dst.dev->features & NETIF_F_UFO)) { | 1220 | int proto = sk->sk_protocol; |
1221 | if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ | ||
1222 | ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen); | ||
1223 | return -EMSGSIZE; | ||
1224 | } | ||
1222 | 1225 | ||
1223 | err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, | 1226 | if (proto == IPPROTO_UDP && |
1224 | fragheaderlen, transhdrlen, mtu, | 1227 | (rt->u.dst.dev->features & NETIF_F_UFO)) { |
1225 | flags); | 1228 | |
1226 | if (err) | 1229 | err = ip6_ufo_append_data(sk, getfrag, from, length, |
1227 | goto error; | 1230 | hh_len, fragheaderlen, |
1228 | return 0; | 1231 | transhdrlen, mtu, flags); |
1232 | if (err) | ||
1233 | goto error; | ||
1234 | return 0; | ||
1235 | } | ||
1229 | } | 1236 | } |
1230 | 1237 | ||
1231 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) | 1238 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) |