/* * IPv6 output functions * Linux INET6 implementation * * Authors: * Pedro Roque <roque@di.fc.ul.pt> * * $Id: ip6_output.c,v 1.34 2002/02/01 22:01:04 davem Exp $ * * Based on linux/net/ipv4/ip_output.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Changes: * A.N.Kuznetsov : airthmetics in fragmentation. * extension headers are implemented. * route changes now work. * ip6_forward does not confuse sniffers. * etc. * * H. von Brand : Added missing #include <linux/string.h> * Imran Patel : frag id should be in NBO * Kazunori MIYAZAWA @USAGI * : add ip6_append_data and related functions * for datagram xmit */#include<linux/errno.h>#include<linux/types.h>#include<linux/string.h>#include<linux/socket.h>#include<linux/net.h>#include<linux/netdevice.h>#include<linux/if_arp.h>#include<linux/in6.h>#include<linux/tcp.h>#include<linux/route.h>#include<linux/module.h>#include<linux/netfilter.h>#include<linux/netfilter_ipv6.h>#include<net/sock.h>#include<net/snmp.h>#include<net/ipv6.h>#include<net/ndisc.h>#include<net/protocol.h>#include<net/ip6_route.h>#include<net/addrconf.h>#include<net/rawv6.h>#include<net/icmp.h>#include<net/xfrm.h>#include<net/checksum.h>staticintip6_fragment(structsk_buff*skb,int(*output)(structsk_buff*));static__inline__voidipv6_select_ident(structsk_buff*skb,structfrag_hdr*fhdr){staticu32ipv6_fragmentation_id=1;staticDEFINE_SPINLOCK(ip6_id_lock);spin_lock_bh(&ip6_id_lock);fhdr->identification=htonl(ipv6_fragmentation_id);if(++ipv6_fragmentation_id==0)ipv6_fragmentation_id=1;spin_unlock_bh(&ip6_id_lock);}staticinlineintip6_output_finish(structsk_buff*skb){structdst_entry*dst=skb->dst;structhh_cache*hh=dst->hh;if(hh){inthh_alen;read_lock_bh(&hh->hh_lock);hh_alen=HH_DATA_ALIGN(hh->hh_len);