X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fip6_output.c;h=5bf70b1442eae1f0be6497774be8ea7ceac9cbf1;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=1d5dfeb2614ea31a4dabca1b74630d6ee16889a0;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 1d5dfeb26..5bf70b144 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) int ip6_output(struct sk_buff *skb) { - if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) || + if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) || dst_allfrag(skb->dst)) return ip6_fragment(skb, ip6_output2); else @@ -161,7 +161,7 @@ int ip6_output(struct sk_buff *skb) int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, struct ipv6_txoptions *opt, int ipfragok) { - struct ipv6_pinfo *np = inet6_sk(sk); + struct ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL; struct in6_addr *first_hop = &fl->fl6_dst; struct dst_entry *dst = skb->dst; struct ipv6hdr *hdr; @@ -733,29 +733,28 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) if (*dst) { struct rt6_info *rt = (struct rt6_info*)*dst; - /* Yes, checking route validity in not connected - * case is not very simple. Take into account, - * that we do not support routing by source, TOS, - * and MSG_DONTROUTE --ANK (980726) - * - * 1. If route was host route, check that - * cached destination is current. - * If it is network route, we still may - * check its validity using saved pointer - * to the last used address: daddr_cache. - * We do not want to save whole address now, - * (because main consumer of this service - * is tcp, which has not this problem), - * so that the last trick works only on connected - * sockets. - * 2. oif also should be the same. - */ + /* Yes, checking route validity in not connected + case is not very simple. Take into account, + that we do not support routing by source, TOS, + and MSG_DONTROUTE --ANK (980726) + + 1. If route was host route, check that + cached destination is current. + If it is network route, we still may + check its validity using saved pointer + to the last used address: daddr_cache. + We do not want to save whole address now, + (because main consumer of this service + is tcp, which has not this problem), + so that the last trick works only on connected + sockets. + 2. oif also should be the same. + */ + if (((rt->rt6i_dst.plen != 128 || - !ipv6_addr_equal(&fl->fl6_dst, - &rt->rt6i_dst.addr)) + !ipv6_addr_equal(&fl->fl6_dst, &rt->rt6i_dst.addr)) && (np->daddr_cache == NULL || - !ipv6_addr_equal(&fl->fl6_dst, - np->daddr_cache))) + !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache))) || (fl->oif && fl->oif != (*dst)->dev->ifindex)) { dst_release(*dst); *dst = NULL; @@ -830,9 +829,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, struct frag_hdr fhdr; /* specify the length of each IP datagram fragment*/ - skb_shinfo(skb)->gso_size = mtu - fragheaderlen - - sizeof(struct frag_hdr); - skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; + skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - + sizeof(struct frag_hdr); ipv6_select_ident(skb, &fhdr); skb_shinfo(skb)->ip6_frag_id = fhdr.identification; __skb_queue_tail(&sk->sk_write_queue, skb); @@ -891,7 +889,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, np->cork.hop_limit = hlimit; np->cork.tclass = tclass; mtu = dst_mtu(rt->u.dst.path); - if (np->frag_size < mtu) { + if (np && np->frag_size < mtu) { if (np->frag_size) mtu = np->frag_size; } @@ -1048,7 +1046,7 @@ alloc_new_skb: skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); data += fraggap; - pskb_trim_unique(skb_prev, maxfraglen); + skb_trim(skb_prev, maxfraglen); } copy = datalen - transhdrlen - fraggap; if (copy < 0) {