18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky  * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Panasas, Inc.
58d59ecb2SHans Petter Selasky  * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky  * All rights reserved.
78d59ecb2SHans Petter Selasky  *
88d59ecb2SHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky  * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky  * are met:
118d59ecb2SHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky  *    notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky  *    disclaimer.
148d59ecb2SHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky  *
188d59ecb2SHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky  */
29307f78f3SVladimir Kondratyev #ifndef _LINUXKPI_NET_IPV6_H_
30307f78f3SVladimir Kondratyev #define	_LINUXKPI_NET_IPV6_H_
318d59ecb2SHans Petter Selasky 
328e7baabcSHans Petter Selasky #include <sys/types.h>
338e7baabcSHans Petter Selasky #include <netinet/in.h>
348e7baabcSHans Petter Selasky #include <linux/types.h>
35762efb2dSBjoern A. Zeeb #include <linux/bitops.h>
368d59ecb2SHans Petter Selasky 
37303bd80aSHans Petter Selasky #define	IPV6_DEFAULT_HOPLIMIT 64
38303bd80aSHans Petter Selasky 
39b9d984e2SBjoern A. Zeeb #define	NEXTHDR_HOP		IPPROTO_HOPOPTS
40b9d984e2SBjoern A. Zeeb #define	NEXTHDR_ROUTING		IPPROTO_ROUTING
41b9d984e2SBjoern A. Zeeb #define	NEXTHDR_NONE		IPPROTO_NONE
42b9d984e2SBjoern A. Zeeb #define	NEXTHDR_DEST		IPPROTO_DSTOPTS
43b9d984e2SBjoern A. Zeeb 
44303bd80aSHans Petter Selasky #define	ipv6_addr_loopback(addr) IN6_IS_ADDR_LOOPBACK(addr)
45303bd80aSHans Petter Selasky #define	ipv6_addr_any(addr) IN6_IS_ADDR_UNSPECIFIED(addr)
46303bd80aSHans Petter Selasky 
478d59ecb2SHans Petter Selasky #define	ipv6_addr_copy(dst, src)			\
488d59ecb2SHans Petter Selasky 	memcpy((dst), (src), sizeof(struct in6_addr))
498d59ecb2SHans Petter Selasky 
508d59ecb2SHans Petter Selasky static inline void
ipv6_ib_mc_map(const struct in6_addr * addr,const unsigned char * broadcast,char * buf)518d59ecb2SHans Petter Selasky ipv6_ib_mc_map(const struct in6_addr *addr, const unsigned char *broadcast,
528d59ecb2SHans Petter Selasky     char *buf)
538d59ecb2SHans Petter Selasky {
548d59ecb2SHans Petter Selasky 	unsigned char scope;
558d59ecb2SHans Petter Selasky 
568d59ecb2SHans Petter Selasky 	scope = broadcast[5] & 0xF;
578d59ecb2SHans Petter Selasky 	buf[0]  = 0;
588d59ecb2SHans Petter Selasky 	buf[1]  = 0xff;
598d59ecb2SHans Petter Selasky 	buf[2]  = 0xff;
608d59ecb2SHans Petter Selasky 	buf[3]  = 0xff;
618d59ecb2SHans Petter Selasky 	buf[4]  = 0xff;
628d59ecb2SHans Petter Selasky 	buf[5]  = 0x10 | scope;
638d59ecb2SHans Petter Selasky 	buf[6]  = 0x60;
648d59ecb2SHans Petter Selasky 	buf[7]  = 0x1b;
658d59ecb2SHans Petter Selasky 	buf[8]  = broadcast[8];
668d59ecb2SHans Petter Selasky 	buf[9]  = broadcast[9];
678d59ecb2SHans Petter Selasky 	memcpy(&buf[10], &addr->s6_addr[6], 10);
688d59ecb2SHans Petter Selasky }
698d59ecb2SHans Petter Selasky 
__ipv6_addr_set_half(__be32 * addr,__be32 wh,__be32 wl)7083630517SEd Maste static inline void __ipv6_addr_set_half(__be32 *addr, __be32 wh, __be32 wl)
718d59ecb2SHans Petter Selasky {
728d59ecb2SHans Petter Selasky #if BITS_PER_LONG == 64
738d59ecb2SHans Petter Selasky #if defined(__BIG_ENDIAN)
748d59ecb2SHans Petter Selasky 	if (__builtin_constant_p(wh) && __builtin_constant_p(wl)) {
758d59ecb2SHans Petter Selasky 		*(__force u64 *)addr = ((__force u64)(wh) << 32 | (__force u64)(wl));
768d59ecb2SHans Petter Selasky 		return;
778d59ecb2SHans Petter Selasky 	}
788d59ecb2SHans Petter Selasky #elif defined(__LITTLE_ENDIAN)
798d59ecb2SHans Petter Selasky 	if (__builtin_constant_p(wl) && __builtin_constant_p(wh)) {
808d59ecb2SHans Petter Selasky 		*(__force u64 *)addr = ((__force u64)(wl) << 32 | (__force u64)(wh));
818d59ecb2SHans Petter Selasky 		return;
828d59ecb2SHans Petter Selasky 	}
838d59ecb2SHans Petter Selasky #endif
848d59ecb2SHans Petter Selasky #endif
858d59ecb2SHans Petter Selasky 	addr[0] = wh;
868d59ecb2SHans Petter Selasky 	addr[1] = wl;
878d59ecb2SHans Petter Selasky }
888d59ecb2SHans Petter Selasky 
ipv6_addr_set(struct in6_addr * addr,__be32 w1,__be32 w2,__be32 w3,__be32 w4)898d59ecb2SHans Petter Selasky static inline void ipv6_addr_set(struct in6_addr *addr,
908d59ecb2SHans Petter Selasky 				     __be32 w1, __be32 w2,
918d59ecb2SHans Petter Selasky 				     __be32 w3, __be32 w4)
928d59ecb2SHans Petter Selasky {
938d59ecb2SHans Petter Selasky 	__ipv6_addr_set_half(&addr->s6_addr32[0], w1, w2);
948d59ecb2SHans Petter Selasky 	__ipv6_addr_set_half(&addr->s6_addr32[2], w3, w4);
958d59ecb2SHans Petter Selasky }
968d59ecb2SHans Petter Selasky 
ipv6_addr_set_v4mapped(const __be32 addr,struct in6_addr * v4mapped)978d59ecb2SHans Petter Selasky static inline void ipv6_addr_set_v4mapped(const __be32 addr,
988d59ecb2SHans Petter Selasky 					  struct in6_addr *v4mapped)
998d59ecb2SHans Petter Selasky {
1008d59ecb2SHans Petter Selasky 	ipv6_addr_set(v4mapped,
1018d59ecb2SHans Petter Selasky 			0, 0,
1028d59ecb2SHans Petter Selasky 			htonl(0x0000FFFF),
1038d59ecb2SHans Petter Selasky 			addr);
1048d59ecb2SHans Petter Selasky }
1058d59ecb2SHans Petter Selasky 
ipv6_addr_v4mapped(const struct in6_addr * a)1068d59ecb2SHans Petter Selasky static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
1078d59ecb2SHans Petter Selasky {
1088d59ecb2SHans Petter Selasky 	return ((a->s6_addr32[0] | a->s6_addr32[1] |
1098d59ecb2SHans Petter Selasky 		(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0);
1108d59ecb2SHans Petter Selasky }
1118d59ecb2SHans Petter Selasky 
ipv6_addr_cmp(const struct in6_addr * a1,const struct in6_addr * a2)1128d59ecb2SHans Petter Selasky static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
1138d59ecb2SHans Petter Selasky {
1148d59ecb2SHans Petter Selasky 	return memcmp(a1, a2, sizeof(struct in6_addr));
1158d59ecb2SHans Petter Selasky }
1168d59ecb2SHans Petter Selasky 
117307f78f3SVladimir Kondratyev #endif	/* _LINUXKPI_NET_IPV6_H_ */
118