Import 2.1.15
[davej-history.git] / net / ipv6 / ipv6_output.c
blobceb0bc72b394806800d7645d6f60611142c310ec
1 /*
2 * IPv6 output functions
3 * Linux INET6 implementation
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
8 * Based on linux/net/ipv4/ip_output.c
10 * $Id: ipv6_output.c,v 1.19 1996/10/16 18:34:16 roque Exp $
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
19 * Changes:
21 * Andi Kleen : exception handling
24 #include <linux/errno.h>
25 #include <linux/types.h>
26 #include <linux/socket.h>
27 #include <linux/sockios.h>
28 #include <linux/sched.h>
29 #include <linux/net.h>
30 #include <linux/netdevice.h>
31 #include <linux/if_arp.h>
32 #include <linux/in6.h>
34 #include <net/sock.h>
35 #include <net/snmp.h>
37 #include <net/ipv6.h>
38 #include <net/ndisc.h>
39 #include <net/protocol.h>
40 #include <net/transp_v6.h>
41 #include <net/ipv6_route.h>
42 #include <net/addrconf.h>
44 static u32 ipv6_fragmentation_id =1;
45 int ipv6_forwarding =0;/* default: host */
47 static int __inline__ ipv6_build_mac_header(struct sk_buff *skb,
48 struct device *dev,
49 struct neighbour *neigh,
50 int len)
52 int mac;
53 int hdrlen =0;
55 skb->arp =1;
56 skb->nexthop = neigh;
58 skb_reserve(skb, (dev->hard_header_len +15) & ~15);
60 if(dev->hard_header_len)
64 * FIXME: use cached hardware header if availiable
66 if(dev->hard_header)
68 mac = dev->hard_header(skb, dev, ETH_P_IPV6,
69 NULL, NULL, len);
71 if(mac <0)
73 hdrlen = -mac;
74 skb->arp =0;
76 else
78 hdrlen = mac;
81 else
82 hdrlen = dev->hard_header_len;
85 skb->mac.raw = skb->data;
86 return hdrlen;
89 voidipv6_redo_mac_hdr(struct sk_buff *skb,struct neighbour *neigh,int len)
91 struct device *dev = neigh->dev;
92 int mac;
94 skb->dev = dev;
95 skb->nexthop = neigh;
96 skb->arp =1;
98 skb_pull(skb, (unsigned char*) skb->nh.ipv6h - skb->data);
101 * neighbour cache should have the ether address
102 * cached... use it
105 if(dev->hard_header)
108 * FIXME: use cached hardware header if availiable
111 mac = dev->hard_header(skb, dev, ETH_P_IPV6,
112 NULL, NULL, len);
114 if(mac <0)
116 skb->arp =0;
120 skb->mac.raw = skb->data;
123 voiddefault_output_method(struct sk_buff *skb,struct rt6_info *rt)
125 struct sock *sk = skb->sk;
126 struct device *dev = skb->dev;
128 if(dev->flags & IFF_UP)
131 * If we have an owner use its priority setting,
132 * otherwise use NORMAL
135 dev_queue_xmit(skb);
137 else
139 if(sk)
140 sk->err = ENETDOWN;
142 ipv6_statistics.Ip6OutDiscards++;
144 kfree_skb(skb, FREE_WRITE);
149 * xmit an sk_buff (used by TCP)
150 * sk can be NULL (for sending RESETs)
152 intipv6_xmit(struct sock *sk,struct sk_buff *skb,struct in6_addr *saddr,
153 struct in6_addr *daddr,struct ipv6_options *opt,int proto)
155 struct ipv6hdr *hdr;
156 struct dest_entry *dc;
157 struct ipv6_pinfo *np = NULL;
158 struct device *dev = skb->dev;
159 int seg_len;
160 int addr_type;
161 int rt_flags =0;
164 addr_type =ipv6_addr_type(daddr);
166 if(addr_type & (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_SITELOCAL))
169 * force device match on route lookup
172 rt_flags |= RTI_DEVRT;
175 if(sk && sk->localroute)
176 rt_flags |= RTI_GATEWAY;
178 hdr = skb->nh.ipv6h;
181 if(sk)
183 np = &sk->net_pinfo.af_inet6;
186 if(np && np->dest)
188 dc =ipv6_dst_check(np->dest, daddr, np->dc_sernum, rt_flags);
190 else
192 dc =ipv6_dst_route(daddr, dev, rt_flags);
195 if(dc == NULL)
197 ipv6_statistics.Ip6OutNoRoutes++;
198 return(-ENETUNREACH);
201 dev = dc->rt.rt_dev;
203 if(saddr == NULL)
205 struct inet6_ifaddr *ifa;
207 ifa =ipv6_get_saddr((struct rt6_info *) dc, daddr);
209 if(ifa == NULL)
211 printk(KERN_DEBUG
212 "ipv6_xmit: get_saddr failed\n");
213 return-ENETUNREACH;
216 saddr = &ifa->addr;
218 if(np)
220 ipv6_addr_copy(&np->saddr, saddr);
224 seg_len = skb->tail - ((unsigned char*) hdr);
227 * Link Layer headers
230 skb->protocol =__constant_htons(ETH_P_IPV6);
231 skb->dev = dev;
233 ipv6_redo_mac_hdr(skb, dc->dc_nexthop, seg_len);
236 * Fill in the IPv6 header
239 hdr->version =6;
240 hdr->priority = np ? np->priority :0;
242 if(np)
243 memcpy(hdr->flow_lbl, (void*) &np->flow_lbl,3);
244 else
245 memset(hdr->flow_lbl,0,3);
247 hdr->payload_len =htons(seg_len -sizeof(struct ipv6hdr));
248 hdr->nexthdr = proto;
249 hdr->hop_limit = np ? np->hop_limit : ipv6_hop_limit;
251 memcpy(&hdr->saddr, saddr,sizeof(struct in6_addr));
252 memcpy(&hdr->daddr, daddr,sizeof(struct in6_addr));
256 * Options
261 * Output the packet
264 ipv6_statistics.Ip6OutRequests++;
266 if(dc->rt.rt_output_method)
268 (*dc->rt.rt_output_method)(skb, (struct rt6_info *) dc);
270 else
271 default_output_method(skb, (struct rt6_info *) dc);
274 * Update serial number of cached dest_entry or
275 * release destination cache entry
278 if(np)
280 np->dest = dc;
281 if(dc->rt.fib_node)
283 np->dc_sernum = dc->rt.fib_node->fn_sernum;
286 else
288 ipv6_dst_unlock(dc);
291 return0;
295 * To avoid extra problems ND packets are send through this
296 * routine. It's code duplication but i really want to avoid
297 * extra checks since ipv6_build_header is used by TCP (which
298 * is for us performace critical)
301 intipv6_bld_hdr_2(struct sock *sk,struct sk_buff *skb,struct device *dev,
302 struct neighbour *neigh,
303 struct in6_addr *saddr,struct in6_addr *daddr,
304 int proto,int len)
306 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
307 struct ipv6hdr *hdr;
308 int hdrlen =0;
310 skb->dev = dev;
312 /* build MAC header */
313 hdrlen +=ipv6_build_mac_header(skb, dev, neigh, len);
315 /* build fixed IPv6 header */
317 if(proto == IPPROTO_RAW)
318 return hdrlen;
321 hdr = (struct ipv6hdr *)skb_put(skb,sizeof(struct ipv6hdr));
322 skb->nh.ipv6h = hdr;
324 hdr->version =6;
325 hdr->priority = np->priority &0x0f;
327 memset(hdr->flow_lbl,0,3);
329 hdr->hop_limit = np->hop_limit;
331 if(saddr == NULL)
333 printk(KERN_DEBUG "bug: bld_hdr called with no saddr\n");
334 return-ENETUNREACH;
337 memcpy(&hdr->saddr, saddr,sizeof(struct in6_addr));
338 memcpy(&hdr->daddr, daddr,sizeof(struct in6_addr));
340 hdrlen +=sizeof(struct ipv6hdr);
342 hdr->nexthdr = proto;
344 return hdrlen;
347 voidipv6_queue_xmit(struct sock *sk,struct device *dev,struct sk_buff *skb,
348 int free)
350 struct ipv6hdr *hdr;
351 u32 seg_len;
353 hdr = skb->nh.ipv6h;
354 skb->protocol =__constant_htons(ETH_P_IPV6);
356 seg_len = skb->tail - ((unsigned char*) hdr);
358 hdr->payload_len =htons(seg_len -sizeof(struct ipv6hdr));
360 if(dev == NULL)
362 printk(KERN_DEBUG "ipv6_queue_xmit: unknown device\n");
363 return;
366 skb->dev = dev;
368 ipv6_statistics.Ip6OutRequests++;
372 * Multicast loopback
375 if(dev->flags & IFF_UP)
378 * If we have an owner use its priority setting,
379 * otherwise use NORMAL
382 dev_queue_xmit(skb);
384 else
386 if(sk)
387 sk->err = ENETDOWN;
389 ipv6_statistics.Ip6OutDiscards++;
391 kfree_skb(skb, FREE_WRITE);
397 intipv6_build_xmit(struct sock *sk, inet_getfrag_t getfrag,const void*data,
398 struct in6_addr *dest,unsigned short int length,
399 struct in6_addr *saddr,struct device *dev,
400 struct ipv6_options *opt,int proto,
401 int noblock)
403 rt6_output_method_t output_method = default_output_method;
404 int hlimit;
405 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
406 struct dest_entry *dc = NULL;
407 struct in6_addr *daddr = dest;
408 struct ipv6hdr *hdr;
409 struct neighbour *neigh;
410 int addr_type;
411 int pktlength;
412 int pmtu =0;
413 int rt_flags =0;
414 int error;
416 if(opt && opt->srcrt)
418 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
419 daddr = rt0->addr;
422 addr_type =ipv6_addr_type(daddr);
423 if(addr_type & IPV6_ADDR_MULTICAST)
425 hlimit = np->mcast_hops;
426 if(dev == NULL)
428 dev = np->mc_if;
431 else
432 hlimit = np->hop_limit;
434 if(addr_type & (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_SITELOCAL |
435 IPV6_ADDR_MULTICAST))
438 * force device match on route lookup
441 rt_flags |= RTI_DEVRT;
444 if(sk->localroute)
446 rt_flags |= RTI_GATEWAY;
449 if(np->dest)
451 np->dest =ipv6_dst_check(np->dest, daddr, np->dc_sernum,
452 rt_flags);
454 dc = np->dest;
456 if(dc && dc->rt.fib_node)
458 np->dc_sernum = dc->rt.fib_node->fn_sernum;
460 else
462 printk(KERN_WARNING "dc entry not in table\n");
465 else
467 dc =ipv6_dst_route(daddr, dev, rt_flags);
470 if(dc == NULL)
472 if((addr_type & IPV6_ADDR_MULTICAST) && dev)
474 neigh = NULL;
475 pmtu = dev->mtu;
477 else
479 ipv6_statistics.Ip6OutNoRoutes++;
480 return(-ENETUNREACH);
483 else
485 neigh = dc->dc_nexthop;
486 dev = neigh->dev;
488 if(dc->rt.rt_output_method)
490 output_method = dc->rt.rt_output_method;
493 if(dc->dc_flags & DCF_PMTU)
494 pmtu = dc->dc_pmtu;
495 else
496 pmtu = dev->mtu;
500 if(saddr == NULL)
502 struct inet6_ifaddr *ifa;
504 ifa =ipv6_get_saddr((struct rt6_info *) dc, daddr);
506 if(ifa == NULL)
508 printk(KERN_DEBUG
509 "ipv6_build_xmit: get_saddr failed\n");
510 return-ENETUNREACH;
513 saddr = &ifa->addr;
516 if(dc && np->dest == NULL)
518 ipv6_dst_unlock(dc);
521 pktlength = length;
523 if(!sk->ip_hdrincl)
525 pktlength +=sizeof(struct ipv6hdr);
526 if(opt)
528 pktlength += opt->opt_flen + opt->opt_nflen;
533 dev_lock_list();
536 * reminder: don't allow fragmentation for IPPROTO_RAW
540 if(pktlength <= pmtu)
542 struct sk_buff *skb =
543 sock_alloc_send_skb(sk, pktlength+15+
544 dev->hard_header_len,
545 0, noblock, &error);
547 if(skb == NULL)
549 ipv6_statistics.Ip6OutDiscards++;
550 dev_unlock_list();
551 return error;
555 skb->dev=dev;
556 skb->protocol =htons(ETH_P_IPV6);
557 skb->when=jiffies;
558 skb->arp=0;
560 /* build the mac header... */
561 ipv6_build_mac_header(skb, dev, neigh, pktlength);
563 hdr = (struct ipv6hdr *) skb->tail;
564 skb->nh.ipv6h = hdr;
566 if(!sk->ip_hdrincl)
568 skb_put(skb,sizeof(struct ipv6hdr));
570 hdr->version =6;
571 hdr->priority = np->priority;
573 memcpy(hdr->flow_lbl, &np->flow_lbl,3);
575 hdr->payload_len =htons(pktlength -
576 sizeof(struct ipv6hdr));
578 hdr->hop_limit = hlimit;
580 memcpy(&hdr->saddr, saddr,sizeof(struct in6_addr));
581 memcpy(&hdr->daddr, daddr,sizeof(struct in6_addr));
583 if(opt && opt->srcrt)
585 hdr->nexthdr =ipv6opt_bld_rthdr(skb, opt,
586 dest, proto);
589 else
590 hdr->nexthdr = proto;
593 skb_put(skb, length);
594 error =getfrag(data, &hdr->saddr,
595 ((char*) hdr) + (pktlength - length),
596 0, length);
598 if(!error)
600 ipv6_statistics.Ip6OutRequests++;
601 (*output_method)(skb, (struct rt6_info *) dc);
602 }else
604 error = -EFAULT;
605 kfree_skb(skb, FREE_WRITE);
608 dev_unlock_list();
609 return error;
611 else
614 * Fragmentation
618 * Extension header order:
619 * Hop-by-hop -> Routing -> Fragment -> rest (...)
621 * We must build the non-fragmented part that
622 * will be in every packet... this also means
623 * that other extension headers (Dest, Auth, etc)
624 * must be considered in the data to be fragmented
627 struct sk_buff *last_skb;
628 struct frag_hdr *fhdr;
629 int unfrag_len;
630 int payl_len;
631 int frag_len;
632 int last_len;
633 int nfrags;
634 int err;
635 int fhdr_dist;
636 __u32 id;
638 if(sk->ip_hdrincl)
640 return-EMSGSIZE;
643 id = ipv6_fragmentation_id++;
645 unfrag_len =sizeof(struct ipv6hdr) +sizeof(struct frag_hdr);
646 payl_len = length;
648 if(opt)
650 unfrag_len += opt->opt_nflen;
651 payl_len += opt->opt_flen;
654 nfrags = payl_len / ((pmtu - unfrag_len) & ~0x7);
657 * Length of fragmented part on every packet but
658 * the last must be an:
659 * "integer multiple of 8 octects".
662 frag_len = (pmtu - unfrag_len) & ~0x7;
665 * We must send from end to start because of
666 * UDP/ICMP checksums. We do a funny trick:
667 * fill the last skb first with the fixed
668 * header (and its data) and then use it
669 * to create the following segments and send it
670 * in the end. If the peer is checking the M_flag
671 * to trigger the reassembly code then this
672 * might be a good idea.
675 last_len = payl_len - (nfrags * frag_len);
677 if(last_len ==0)
679 last_len = frag_len;
680 nfrags--;
683 last_skb =sock_alloc_send_skb(sk, unfrag_len + frag_len +
684 dev->hard_header_len +15,
685 0, noblock, &err);
687 if(last_skb == NULL)
689 dev_unlock_list();
690 return err;
693 last_skb->dev=dev;
694 last_skb->protocol =htons(ETH_P_IPV6);
695 last_skb->when=jiffies;
696 last_skb->arp=0;
699 * build the mac header...
701 ipv6_build_mac_header(last_skb, dev, neigh,
702 unfrag_len + frag_len);
704 hdr = (struct ipv6hdr *)skb_put(last_skb,
705 sizeof(struct ipv6hdr));
706 last_skb->nh.ipv6h = hdr;
708 hdr->version =6;
709 hdr->priority = np->priority;
711 memcpy(hdr->flow_lbl, &np->flow_lbl,3);
712 hdr->payload_len =htons(unfrag_len + frag_len -
713 sizeof(struct ipv6hdr));
715 hdr->hop_limit = hlimit;
717 hdr->nexthdr = NEXTHDR_FRAGMENT;
719 memcpy(&hdr->saddr, saddr,sizeof(struct in6_addr));
720 memcpy(&hdr->daddr, daddr,sizeof(struct in6_addr));
722 if(opt && opt->srcrt)
724 hdr->nexthdr =ipv6opt_bld_rthdr(last_skb, opt, dest,
725 NEXTHDR_FRAGMENT);
728 fhdr = (struct frag_hdr *)
729 skb_put(last_skb,sizeof(struct frag_hdr));
731 memset(fhdr,0,sizeof(struct frag_hdr));
733 fhdr->nexthdr = proto;
734 fhdr->frag_off =ntohs(nfrags * frag_len);
735 fhdr->identification = id;
737 fhdr_dist = (unsigned char*) fhdr - last_skb->data;
739 error =getfrag(data, &hdr->saddr, last_skb->tail,
740 nfrags * frag_len, last_len);
742 if(!error)
744 while(nfrags--)
746 struct sk_buff *skb;
748 struct frag_hdr *fhdr2;
750 printk(KERN_DEBUG "sending frag %d\n", nfrags);
751 skb =skb_copy(last_skb, sk->allocation);
753 fhdr2 = (struct frag_hdr *)
754 (skb->data + fhdr_dist);
756 /* more flag on */
757 fhdr2->frag_off =ntohs(nfrags * frag_len +1);
760 * FIXME:
761 * if (nfrags == 0)
762 * put rest of headers
765 error =getfrag(data, &hdr->saddr,
766 skb_put(skb, frag_len),
767 nfrags * frag_len, frag_len);
769 if(error)
771 kfree_skb(skb, FREE_WRITE);
772 break;
775 ipv6_statistics.Ip6OutRequests++;
776 (*output_method)(skb, (struct rt6_info *) dc);
780 if(error)
782 kfree_skb(last_skb, FREE_WRITE);
783 dev_unlock_list();
784 return-EFAULT;
787 printk(KERN_DEBUG "sending last frag\n");
789 hdr->payload_len =htons(unfrag_len + last_len -
790 sizeof(struct ipv6hdr));
793 * update last_skb to reflect the getfrag we did
794 * on start.
796 last_skb->tail += last_len;
797 last_skb->len += last_len;
800 * toss the mac header out and rebuild it.
801 * needed because of the different frame length.
802 * ie: not needed for an ethernet.
805 if(dev->type != ARPHRD_ETHER && last_len != frag_len)
807 ipv6_redo_mac_hdr(last_skb, neigh,
808 unfrag_len + last_len);
811 ipv6_statistics.Ip6OutRequests++;
812 (*output_method)(last_skb, (struct rt6_info *) dc);
814 dev_unlock_list();
815 return0;
817 return-1;
820 static int pri_values[4] =
822 SOPRI_BACKGROUND,
823 SOPRI_NORMAL,
824 SOPRI_NORMAL,
825 SOPRI_INTERACTIVE
828 voidipv6_forward(struct sk_buff *skb,struct device *dev,int flags)
830 struct neighbour *neigh;
831 struct dest_entry *dest;
832 int priority;
833 int rt_flags;
834 int size;
835 int pmtu;
837 if(skb->nh.ipv6h->hop_limit <=1)
839 icmpv6_send(skb, ICMPV6_TIME_EXCEEDED, ICMPV6_EXC_HOPLIMIT,
840 0, dev);
842 kfree_skb(skb, FREE_READ);
843 return;
846 skb->nh.ipv6h->hop_limit--;
848 if(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)
850 printk(KERN_DEBUG "ipv6_forward: link local source addr\n");
851 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR,
852 0, dev);
853 kfree_skb(skb, FREE_READ);
854 return;
857 rt_flags = RTF_MODIFIED;
859 if((flags & IP6_FW_STRICT))
861 rt_flags |= RTF_GATEWAY;
864 dest =ipv6_dst_route(&skb->nh.ipv6h->daddr, NULL, rt_flags);
866 if(dest == NULL)
868 int code;
870 if(flags & IP6_FW_STRICT)
871 code = ICMPV6_NOT_NEIGHBOUR;
872 else
873 code = ICMPV6_NOROUTE;
875 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code,0, dev);
877 kfree_skb(skb, FREE_READ);
878 return;
881 neigh = dest->dc_nexthop;
883 if(neigh->dev == dev && (dev->flags & IFF_MULTICAST) &&
884 !(flags & IP6_FW_SRCRT))
886 struct in6_addr *target = NULL;
887 struct nd_neigh *ndn = (struct nd_neigh *) neigh;
890 * outgoing device equal to incoming device
891 * send a redirect
894 if((dest->dc_flags & RTF_GATEWAY))
896 target = &ndn->ndn_addr;
898 else
900 target = &skb->nh.ipv6h->daddr;
903 ndisc_send_redirect(skb, neigh, target);
906 pmtu = neigh->dev->mtu;
908 size =sizeof(struct ipv6hdr) +ntohs(skb->nh.ipv6h->payload_len);
910 if(size > pmtu)
912 icmpv6_send(skb, ICMPV6_PKT_TOOBIG,0, pmtu, dev);
913 kfree_skb(skb, FREE_READ);
914 return;
917 ipv6_dst_unlock(dest);
919 if(skb_headroom(skb) < neigh->dev->hard_header_len)
921 struct sk_buff *buff;
923 buff =alloc_skb(neigh->dev->hard_header_len + skb->len +15,
924 GFP_ATOMIC);
926 if(buff == NULL)
928 return;
931 skb_reserve(buff, (neigh->dev->hard_header_len +15) & ~15);
933 buff->protocol =__constant_htons(ETH_P_IPV6);
934 buff->h.raw =skb_put(buff, size);
936 memcpy(buff->h.raw, skb->nh.ipv6h, size);
937 buff->nh.ipv6h = (struct ipv6hdr *) buff->h.raw;
938 kfree_skb(skb, FREE_READ);
939 skb = buff;
942 ipv6_redo_mac_hdr(skb, neigh, size);
944 priority = skb->nh.ipv6h->priority;
946 priority = (priority &0x7) >>1;
947 priority = pri_values[priority];
949 if(dev->flags & IFF_UP)
951 skb->dev = neigh->dev;
952 dev_queue_xmit(skb);
954 else
956 ipv6_statistics.Ip6OutDiscards++;
957 kfree_skb(skb, FREE_READ);
963 * Local variables:
964 * c-file-style: "Linux"
965 * End:
close