2 * IPv6 output functions 3 * Linux INET6 implementation 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. 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> 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
, 49 struct neighbour
*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 68 mac
= dev
->hard_header(skb
, dev
, ETH_P_IPV6
, 82 hdrlen
= dev
->hard_header_len
; 85 skb
->mac
.raw
= skb
->data
; 89 voidipv6_redo_mac_hdr(struct sk_buff
*skb
,struct neighbour
*neigh
,int len
) 91 struct device
*dev
= neigh
->dev
; 98 skb_pull(skb
, (unsigned char*) skb
->nh
.ipv6h
- skb
->data
); 101 * neighbour cache should have the ether address 108 * FIXME: use cached hardware header if availiable 111 mac
= dev
->hard_header(skb
, dev
, ETH_P_IPV6
, 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 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
) 156 struct dest_entry
*dc
; 157 struct ipv6_pinfo
*np
= NULL
; 158 struct device
*dev
= skb
->dev
; 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
; 183 np
= &sk
->net_pinfo
.af_inet6
; 188 dc
=ipv6_dst_check(np
->dest
, daddr
, np
->dc_sernum
, rt_flags
); 192 dc
=ipv6_dst_route(daddr
, dev
, rt_flags
); 197 ipv6_statistics
.Ip6OutNoRoutes
++; 198 return(-ENETUNREACH
); 205 struct inet6_ifaddr
*ifa
; 207 ifa
=ipv6_get_saddr((struct rt6_info
*) dc
, daddr
); 212 "ipv6_xmit: get_saddr failed\n"); 220 ipv6_addr_copy(&np
->saddr
, saddr
); 224 seg_len
= skb
->tail
- ((unsigned char*) hdr
); 230 skb
->protocol
=__constant_htons(ETH_P_IPV6
); 233 ipv6_redo_mac_hdr(skb
, dc
->dc_nexthop
, seg_len
); 236 * Fill in the IPv6 header 240 hdr
->priority
= np
? np
->priority
:0; 243 memcpy(hdr
->flow_lbl
, (void*) &np
->flow_lbl
,3); 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
)); 264 ipv6_statistics
.Ip6OutRequests
++; 266 if(dc
->rt
.rt_output_method
) 268 (*dc
->rt
.rt_output_method
)(skb
, (struct rt6_info
*) dc
); 271 default_output_method(skb
, (struct rt6_info
*) dc
); 274 * Update serial number of cached dest_entry or 275 * release destination cache entry 283 np
->dc_sernum
= dc
->rt
.fib_node
->fn_sernum
; 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
, 306 struct ipv6_pinfo
*np
= &sk
->net_pinfo
.af_inet6
; 312 /* build MAC header */ 313 hdrlen
+=ipv6_build_mac_header(skb
, dev
, neigh
, len
); 315 /* build fixed IPv6 header */ 317 if(proto
== IPPROTO_RAW
) 321 hdr
= (struct ipv6hdr
*)skb_put(skb
,sizeof(struct ipv6hdr
)); 325 hdr
->priority
= np
->priority
&0x0f; 327 memset(hdr
->flow_lbl
,0,3); 329 hdr
->hop_limit
= np
->hop_limit
; 333 printk(KERN_DEBUG
"bug: bld_hdr called with no saddr\n"); 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
; 347 voidipv6_queue_xmit(struct sock
*sk
,struct device
*dev
,struct sk_buff
*skb
, 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
)); 362 printk(KERN_DEBUG
"ipv6_queue_xmit: unknown device\n"); 368 ipv6_statistics
.Ip6OutRequests
++; 375 if(dev
->flags
& IFF_UP
) 378 * If we have an owner use its priority setting, 379 * otherwise use NORMAL 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
, 403 rt6_output_method_t output_method
= default_output_method
; 405 struct ipv6_pinfo
*np
= &sk
->net_pinfo
.af_inet6
; 406 struct dest_entry
*dc
= NULL
; 407 struct in6_addr
*daddr
= dest
; 409 struct neighbour
*neigh
; 416 if(opt
&& opt
->srcrt
) 418 struct rt0_hdr
*rt0
= (struct rt0_hdr
*) opt
->srcrt
; 422 addr_type
=ipv6_addr_type(daddr
); 423 if(addr_type
& IPV6_ADDR_MULTICAST
) 425 hlimit
= np
->mcast_hops
; 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
; 446 rt_flags
|= RTI_GATEWAY
; 451 np
->dest
=ipv6_dst_check(np
->dest
, daddr
, np
->dc_sernum
, 456 if(dc
&& dc
->rt
.fib_node
) 458 np
->dc_sernum
= dc
->rt
.fib_node
->fn_sernum
; 462 printk(KERN_WARNING
"dc entry not in table\n"); 467 dc
=ipv6_dst_route(daddr
, dev
, rt_flags
); 472 if((addr_type
& IPV6_ADDR_MULTICAST
) && dev
) 479 ipv6_statistics
.Ip6OutNoRoutes
++; 480 return(-ENETUNREACH
); 485 neigh
= dc
->dc_nexthop
; 488 if(dc
->rt
.rt_output_method
) 490 output_method
= dc
->rt
.rt_output_method
; 493 if(dc
->dc_flags
& DCF_PMTU
) 502 struct inet6_ifaddr
*ifa
; 504 ifa
=ipv6_get_saddr((struct rt6_info
*) dc
, daddr
); 509 "ipv6_build_xmit: get_saddr failed\n"); 516 if(dc
&& np
->dest
== NULL
) 525 pktlength
+=sizeof(struct ipv6hdr
); 528 pktlength
+= opt
->opt_flen
+ opt
->opt_nflen
; 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
, 549 ipv6_statistics
.Ip6OutDiscards
++; 556 skb
->protocol
=htons(ETH_P_IPV6
); 560 /* build the mac header... */ 561 ipv6_build_mac_header(skb
, dev
, neigh
, pktlength
); 563 hdr
= (struct ipv6hdr
*) skb
->tail
; 568 skb_put(skb
,sizeof(struct ipv6hdr
)); 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
, 590 hdr
->nexthdr
= proto
; 593 skb_put(skb
, length
); 594 error
=getfrag(data
, &hdr
->saddr
, 595 ((char*) hdr
) + (pktlength
- length
), 600 ipv6_statistics
.Ip6OutRequests
++; 601 (*output_method
)(skb
, (struct rt6_info
*) dc
); 605 kfree_skb(skb
, FREE_WRITE
); 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
; 643 id
= ipv6_fragmentation_id
++; 645 unfrag_len
=sizeof(struct ipv6hdr
) +sizeof(struct frag_hdr
); 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
); 683 last_skb
=sock_alloc_send_skb(sk
, unfrag_len
+ frag_len
+ 684 dev
->hard_header_len
+15, 694 last_skb
->protocol
=htons(ETH_P_IPV6
); 695 last_skb
->when
=jiffies
; 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
; 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
, 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
); 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
); 757 fhdr2
->frag_off
=ntohs(nfrags
* frag_len
+1); 762 * put rest of headers 765 error
=getfrag(data
, &hdr
->saddr
, 766 skb_put(skb
, frag_len
), 767 nfrags
* frag_len
, frag_len
); 771 kfree_skb(skb
, FREE_WRITE
); 775 ipv6_statistics
.Ip6OutRequests
++; 776 (*output_method
)(skb
, (struct rt6_info
*) dc
); 782 kfree_skb(last_skb
, FREE_WRITE
); 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 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
); 820 static int pri_values
[4] = 828 voidipv6_forward(struct sk_buff
*skb
,struct device
*dev
,int flags
) 830 struct neighbour
*neigh
; 831 struct dest_entry
*dest
; 837 if(skb
->nh
.ipv6h
->hop_limit
<=1) 839 icmpv6_send(skb
, ICMPV6_TIME_EXCEEDED
, ICMPV6_EXC_HOPLIMIT
, 842 kfree_skb(skb
, FREE_READ
); 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
, 853 kfree_skb(skb
, FREE_READ
); 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
); 870 if(flags
& IP6_FW_STRICT
) 871 code
= ICMPV6_NOT_NEIGHBOUR
; 873 code
= ICMPV6_NOROUTE
; 875 icmpv6_send(skb
, ICMPV6_DEST_UNREACH
, code
,0, dev
); 877 kfree_skb(skb
, FREE_READ
); 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 894 if((dest
->dc_flags
& RTF_GATEWAY
)) 896 target
= &ndn
->ndn_addr
; 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
); 912 icmpv6_send(skb
, ICMPV6_PKT_TOOBIG
,0, pmtu
, dev
); 913 kfree_skb(skb
, FREE_READ
); 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, 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
); 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
; 956 ipv6_statistics
.Ip6OutDiscards
++; 957 kfree_skb(skb
, FREE_READ
); 964 * c-file-style: "Linux"