From 12173d801dbbe1950befa35386f584c2841de6a6 Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Wed, 31 Dec 2003 20:27:45 -0800 Subject: [PATCH] [IPV6]: Kill obsolete functions (ip6_frag_xmit() and ip6_build_xmit()). --- include/net/ipv6.h | 7 - net/ipv6/ip6_output.c | 416 ------------------------------------------ 2 files changed, 423 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 18020987d3698..6ac444968292e 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -329,13 +329,6 @@ extern int ip6_nd_hdr(struct sock *sk, struct in6_addr *daddr, int proto, int len); -extern int ip6_build_xmit(struct sock *sk, - inet_getfrag_t getfrag, - const void *data, - struct flowi *fl, - unsigned length, - struct ipv6_txoptions *opt, - int hlimit, int flags); extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); extern int ip6_append_data(struct sock *sk, diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d7d37e7910cf2..4c3189de22494 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -304,422 +304,6 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev, return 0; } -static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, struct flowi *fl, - int hlimit, unsigned pktlength) -{ - struct ipv6hdr *hdr; - - skb->nh.raw = skb_put(skb, sizeof(struct ipv6hdr)); - hdr = skb->nh.ipv6h; - - *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000); - - hdr->payload_len = htons(pktlength - sizeof(struct ipv6hdr)); - hdr->hop_limit = hlimit; - hdr->nexthdr = fl->proto; - - ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); - ipv6_addr_copy(&hdr->daddr, &fl->fl6_dst); - return hdr; -} - -static __inline__ u8 * ipv6_build_fraghdr(struct sk_buff *skb, u8* prev_hdr, unsigned offset) -{ - struct frag_hdr *fhdr; - - fhdr = (struct frag_hdr *) skb_put(skb, sizeof(struct frag_hdr)); - - fhdr->nexthdr = *prev_hdr; - *prev_hdr = NEXTHDR_FRAGMENT; - prev_hdr = &fhdr->nexthdr; - - fhdr->reserved = 0; - fhdr->frag_off = htons(offset); - ipv6_select_ident(skb, fhdr); - return &fhdr->nexthdr; -} - -static int ip6_frag_xmit(struct sock *sk, inet_getfrag_t getfrag, - const void *data, struct dst_entry *dst, - struct flowi *fl, struct ipv6_txoptions *opt, - struct in6_addr *final_dst, - int hlimit, int flags, unsigned length, int mtu) -{ - struct ipv6hdr *hdr; - struct sk_buff *last_skb; - u8 *prev_hdr; - int unfrag_len; - int frag_len; - int last_len; - int nfrags; - int fhdr_dist; - int frag_off; - int data_off; - int err; - - /* - * Fragmentation - * - * Extension header order: - * Hop-by-hop -> Dest0 -> Routing -> Fragment -> Auth -> Dest1 -> rest (...) - * - * We must build the non-fragmented part that - * will be in every packet... this also means - * that other extension headers (Dest, Auth, etc) - * must be considered in the data to be fragmented - */ - - unfrag_len = sizeof(struct ipv6hdr) + sizeof(struct frag_hdr); - last_len = length; - - if (opt) { - unfrag_len += opt->opt_nflen; - last_len += opt->opt_flen; - } - - /* - * Length of fragmented part on every packet but - * the last must be an: - * "integer multiple of 8 octets". - */ - - frag_len = (mtu - unfrag_len) & ~0x7; - - /* Unfragmentable part exceeds mtu. */ - if (frag_len <= 0) { - ipv6_local_error(sk, EMSGSIZE, fl, mtu); - return -EMSGSIZE; - } - - nfrags = last_len / frag_len; - - /* - * We must send from end to start because of - * UDP/ICMP checksums. We do a funny trick: - * fill the last skb first with the fixed - * header (and its data) and then use it - * to create the following segments and send it - * in the end. If the peer is checking the M_flag - * to trigger the reassembly code then this - * might be a good idea. - */ - - frag_off = nfrags * frag_len; - last_len -= frag_off; - - if (last_len == 0) { - last_len = frag_len; - frag_off -= frag_len; - nfrags--; - } - data_off = frag_off; - - /* And it is implementation problem: for now we assume, that - all the exthdrs will fit to the first fragment. - */ - if (opt) { - if (frag_len < opt->opt_flen) { - ipv6_local_error(sk, EMSGSIZE, fl, mtu); - return -EMSGSIZE; - } - data_off = frag_off - opt->opt_flen; - } - - if (flags&MSG_PROBE) - return 0; - - last_skb = sock_alloc_send_skb(sk, unfrag_len + frag_len + - dst->dev->hard_header_len + 15, - flags & MSG_DONTWAIT, &err); - - if (last_skb == NULL) - return err; - - last_skb->dst = dst_clone(dst); - - skb_reserve(last_skb, (dst->dev->hard_header_len + 15) & ~15); - - hdr = ip6_bld_1(sk, last_skb, fl, hlimit, frag_len+unfrag_len); - prev_hdr = &hdr->nexthdr; - - if (opt && opt->opt_nflen) - prev_hdr = ipv6_build_nfrag_opts(last_skb, prev_hdr, opt, final_dst, 0); - - prev_hdr = ipv6_build_fraghdr(last_skb, prev_hdr, frag_off); - fhdr_dist = prev_hdr - last_skb->data; - - err = getfrag(data, &hdr->saddr, last_skb->tail, data_off, last_len); - - if (!err) { - while (nfrags--) { - struct sk_buff *skb; - - struct frag_hdr *fhdr2; - - skb = skb_copy(last_skb, sk->sk_allocation); - - if (skb == NULL) { - IP6_INC_STATS(Ip6FragFails); - kfree_skb(last_skb); - return -ENOMEM; - } - - frag_off -= frag_len; - data_off -= frag_len; - - fhdr2 = (struct frag_hdr *) (skb->data + fhdr_dist); - - /* more flag on */ - fhdr2->frag_off = htons(frag_off | 1); - - /* Write fragmentable exthdrs to the first chunk */ - if (nfrags == 0 && opt && opt->opt_flen) { - ipv6_build_frag_opts(skb, &fhdr2->nexthdr, opt); - frag_len -= opt->opt_flen; - data_off = 0; - } - - err = getfrag(data, &hdr->saddr,skb_put(skb, frag_len), - data_off, frag_len); - - if (err) { - kfree_skb(skb); - break; - } - - IP6_INC_STATS(Ip6FragCreates); - IP6_INC_STATS(Ip6OutRequests); - err = NF_HOOK(PF_INET6,NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); - if (err) { - kfree_skb(last_skb); - return err; - } - } - } - - if (err) { - IP6_INC_STATS(Ip6FragFails); - kfree_skb(last_skb); - return -EFAULT; - } - - hdr->payload_len = htons(unfrag_len + last_len - sizeof(struct ipv6hdr)); - - /* - * update last_skb to reflect the getfrag we did - * on start. - */ - - skb_put(last_skb, last_len); - - IP6_INC_STATS(Ip6FragCreates); - IP6_INC_STATS(Ip6FragOKs); - IP6_INC_STATS(Ip6OutRequests); - return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, last_skb, NULL,dst->dev, ip6_maybe_reroute); -} - -int ip6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data, - struct flowi *fl, unsigned length, - struct ipv6_txoptions *opt, int hlimit, int flags) -{ - struct inet_opt *inet = inet_sk(sk); - struct ipv6_pinfo *np = inet6_sk(sk); - struct in6_addr final_dst_buf, *final_dst = NULL; - struct dst_entry *dst; - int err = 0; - unsigned int pktlength, jumbolen, mtu; - - if (opt && opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; - ipv6_addr_copy(&final_dst_buf, &fl->fl6_dst); - final_dst = &final_dst_buf; - ipv6_addr_copy(&fl->fl6_dst, rt0->addr); - } - - if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) - fl->oif = np->mcast_oif; - - dst = __sk_dst_check(sk, np->dst_cookie); - 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. - */ - - if (((rt->rt6i_dst.plen != 128 || - ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr)) - && (np->daddr_cache == NULL || - ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache))) - || (fl->oif && fl->oif != dst->dev->ifindex)) { - dst = NULL; - } else - dst_hold(dst); - } - - if (dst == NULL) - dst = ip6_route_output(sk, fl); - - if (dst->error) { - IP6_INC_STATS(Ip6OutNoRoutes); - dst_release(dst); - return -ENETUNREACH; - } - - if (ipv6_addr_any(&fl->fl6_src)) { - err = ipv6_get_saddr(dst, &fl->fl6_dst, &fl->fl6_src); - - if (err) { -#if IP6_DEBUG >= 2 - printk(KERN_DEBUG "ip6_build_xmit: " - "no available source address\n"); -#endif - goto out; - } - } - pktlength = length; - - if (dst) { - if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) { - dst_release(dst); - return -ENETUNREACH; - } - } - - if (hlimit < 0) { - if (ipv6_addr_is_multicast(&fl->fl6_dst)) - hlimit = np->mcast_hops; - else - hlimit = np->hop_limit; - if (hlimit < 0) - hlimit = dst_metric(dst, RTAX_HOPLIMIT); - } - - jumbolen = 0; - - if (!inet->hdrincl) { - pktlength += sizeof(struct ipv6hdr); - if (opt) - pktlength += opt->opt_flen + opt->opt_nflen; - - if (pktlength > sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { - /* Jumbo datagram. - It is assumed, that in the case of hdrincl - jumbo option is supplied by user. - */ - pktlength += 8; - jumbolen = pktlength - sizeof(struct ipv6hdr); - } - } - - mtu = dst_pmtu(dst); - if (np->frag_size < mtu) { - if (np->frag_size) - mtu = np->frag_size; - else if (np->pmtudisc == IPV6_PMTUDISC_DONT) - mtu = IPV6_MIN_MTU; - } - - /* Critical arithmetic overflow check. - FIXME: may gcc optimize it out? --ANK (980726) - */ - if (pktlength < length) { - ipv6_local_error(sk, EMSGSIZE, fl, mtu); - err = -EMSGSIZE; - goto out; - } - - if (flags&MSG_CONFIRM) - dst_confirm(dst); - - if (pktlength <= mtu) { - struct sk_buff *skb; - struct ipv6hdr *hdr; - struct net_device *dev = dst->dev; - - err = 0; - if (flags&MSG_PROBE) - goto out; - /* alloc skb with mtu as we do in the IPv4 stack for IPsec */ - skb = sock_alloc_send_skb(sk, mtu + LL_RESERVED_SPACE(dev), - flags & MSG_DONTWAIT, &err); - - if (skb == NULL) { - IP6_INC_STATS(Ip6OutDiscards); - goto out; - } - - skb->dst = dst_clone(dst); - - skb_reserve(skb, (dev->hard_header_len + 15) & ~15); - - hdr = (struct ipv6hdr *) skb->tail; - skb->nh.ipv6h = hdr; - - if (!inet->hdrincl) { - ip6_bld_1(sk, skb, fl, hlimit, - jumbolen ? sizeof(struct ipv6hdr) : pktlength); - - if (opt || jumbolen) { - u8 *prev_hdr = &hdr->nexthdr; - prev_hdr = ipv6_build_nfrag_opts(skb, prev_hdr, opt, final_dst, jumbolen); - if (opt && opt->opt_flen) - ipv6_build_frag_opts(skb, prev_hdr, opt); - } - } - - skb_put(skb, length); - err = getfrag(data, &hdr->saddr, - ((char *) hdr) + (pktlength - length), - 0, length); - if (!opt || !opt->dst1opt) - skb->h.raw = ((char *) hdr) + (pktlength - length); - - if (!err) { - IP6_INC_STATS(Ip6OutRequests); - err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); - } else { - err = -EFAULT; - kfree_skb(skb); - } - } else { - if (inet->hdrincl || jumbolen || - np->pmtudisc == IPV6_PMTUDISC_DO) { - ipv6_local_error(sk, EMSGSIZE, fl, mtu); - err = -EMSGSIZE; - goto out; - } - - err = ip6_frag_xmit(sk, getfrag, data, dst, fl, opt, final_dst, hlimit, - flags, length, mtu); - } - - /* - * cleanup - */ -out: - ip6_dst_store(sk, dst, - !ipv6_addr_cmp(&fl->fl6_dst, &np->daddr) ? - &np->daddr : NULL); - if (err > 0) - err = np->recverr ? net_xmit_errno(err) : 0; - return err; -} - int ip6_call_ra_chain(struct sk_buff *skb, int sel) { struct ip6_ra_chain *ra; -- 2.53.0