Blame iscsiuio/src/uip/ipv6.h

Packit eace71
/*
Packit eace71
 * Copyright (c) 2011, Broadcom Corporation
Packit eace71
 * Copyright (c) 2014, QLogic Corporation
Packit eace71
 *
Packit eace71
 * Written by:  Eddie Wai  (eddie.wai@broadcom.com)
Packit eace71
 *              Based on Kevin Tran's iSCSI boot code
Packit eace71
 *
Packit eace71
 * All rights reserved.
Packit eace71
 *
Packit eace71
 * Redistribution and use in source and binary forms, with or without
Packit eace71
 * modification, are permitted provided that the following conditions
Packit eace71
 * are met:
Packit eace71
 * 1. Redistributions of source code must retain the above copyright
Packit eace71
 *    notice, this list of conditions and the following disclaimer.
Packit eace71
 * 2. Redistributions in binary form must reproduce the above copyright
Packit eace71
 *    notice, this list of conditions and the following disclaimer in the
Packit eace71
 *    documentation and/or other materials provided with the distribution.
Packit eace71
 * 3. All advertising materials mentioning features or use of this software
Packit eace71
 *    must display the following acknowledgement:
Packit eace71
 *      This product includes software developed by Adam Dunkels.
Packit eace71
 * 4. The name of the author may not be used to endorse or promote
Packit eace71
 *    products derived from this software without specific prior
Packit eace71
 *    written permission.
Packit eace71
 *
Packit eace71
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
Packit eace71
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Packit eace71
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit eace71
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
Packit eace71
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit eace71
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
Packit eace71
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit eace71
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
Packit eace71
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit eace71
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit eace71
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit eace71
 *
Packit eace71
 * ipv6.h -  This file contains macro definitions pertaining to IPv6.
Packit eace71
 *
Packit eace71
 *     RFC 2460 : IPv6 Specification.
Packit eace71
 *     RFC 2373 : IPv6 Addressing Architecture.
Packit eace71
 *     RFC 2462 : IPv6 Stateless Address Autoconfiguration.
Packit eace71
 *     RFC 2464 : Transmission of IPv6 Packets over Ethernet Networks.
Packit eace71
 *
Packit eace71
 */
Packit eace71
#ifndef __IPV6_H__
Packit eace71
#define __IPV6_H__
Packit eace71
Packit eace71
#include "ipv6_ndpc.h"
Packit eace71
Packit eace71
#define FALSE 0
Packit eace71
#define TRUE  1
Packit eace71
Packit eace71
#define LINK_LOCAL_PREFIX_LENGTH	2
Packit eace71
#define LAYER2_HEADER_LENGTH		14
Packit eace71
#define LAYER2_VLAN_HEADER_LENGTH	16
Packit eace71
#define LAYER2_TYPE_IPV6		0x86dd
Packit eace71
Packit eace71
struct ipv6_addr {
Packit eace71
	union {
Packit eace71
		u8_t addr8[16];
Packit eace71
		u16_t addr16[8];
Packit eace71
		u32_t addr[4];
Packit eace71
	};
Packit eace71
};
Packit eace71
Packit eace71
struct udp_hdr {
Packit eace71
	u16_t src_port;
Packit eace71
	u16_t dest_port;
Packit eace71
	u16_t length;
Packit eace71
	u16_t chksum;
Packit eace71
};
Packit eace71
Packit eace71
struct mac_address {
Packit eace71
	union {
Packit eace71
		u8_t addr[6];
Packit eace71
		struct {
Packit eace71
			u16_t first_2_bytes;
Packit eace71
			u32_t last_4_bytes;
Packit eace71
		} __attribute__ ((packed));
Packit eace71
	};
Packit eace71
};
Packit eace71
Packit eace71
#define HOST_TO_NET16(a) htons(a)
Packit eace71
#define HOST_TO_NET32(a) htonl(a)
Packit eace71
#define NET_TO_HOST16(a) ntohs(a)
Packit eace71
/*
Packit eace71
 * Local definition for masks
Packit eace71
 */
Packit eace71
#define IPV6_MASK0   { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }
Packit eace71
#define IPV6_MASK32  { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
			   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }
Packit eace71
#define IPV6_MASK64  { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
Packit eace71
			   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }
Packit eace71
#define IPV6_MASK96  { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
Packit eace71
			   0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }
Packit eace71
#define IPV6_MASK128 { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
Packit eace71
			   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
Packit eace71
Packit eace71
#ifdef BIG_ENDIAN
Packit eace71
#define IPV6_ADDR_INT32_ONE     1
Packit eace71
#define IPV6_ADDR_INT32_TWO     2
Packit eace71
#define IPV6_ADDR_INT32_MNL     0xff010000
Packit eace71
#define IPV6_ADDR_INT32_MLL     0xff020000
Packit eace71
#define IPV6_ADDR_INT32_SMP     0x0000ffff
Packit eace71
#define IPV6_ADDR_INT16_ULL     0xfe80
Packit eace71
#define IPV6_ADDR_INT16_USL     0xfec0
Packit eace71
#define IPV6_ADDR_INT16_MLL     0xff02
Packit eace71
#else /* LITTE ENDIAN */
Packit eace71
#define IPV6_ADDR_INT32_ONE     0x01000000
Packit eace71
#define IPV6_ADDR_INT32_TWO     0x02000000
Packit eace71
#define IPV6_ADDR_INT32_MNL     0x000001ff
Packit eace71
#define IPV6_ADDR_INT32_MLL     0x000002ff
Packit eace71
#define IPV6_ADDR_INT32_SMP     0xffff0000
Packit eace71
#define IPV6_ADDR_INT16_ULL     0x80fe
Packit eace71
#define IPV6_ADDR_INT16_USL     0xc0fe
Packit eace71
#define IPV6_ADDR_INT16_MLL     0x02ff
Packit eace71
#endif
Packit eace71
Packit eace71
/*
Packit eace71
 * Definition of some useful macros to handle IP6 addresses
Packit eace71
 */
Packit eace71
#define IPV6_ADDR_ANY_INIT \
Packit eace71
	{ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }
Packit eace71
#define IPV6_ADDR_LOOPBACK_INIT \
Packit eace71
	{ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
Packit eace71
#define IPV6_ADDR_NODELOCAL_ALLNODES_INIT \
Packit eace71
	{ { { 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
Packit eace71
#define IPV6_ADDR_INTFACELOCAL_ALLNODES_INIT \
Packit eace71
	{ { { 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
Packit eace71
#define IPV6_ADDR_LINKLOCAL_ALLNODES_INIT \
Packit eace71
	{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
Packit eace71
#define IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT \
Packit eace71
	{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
Packit eace71
	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
Packit eace71
Packit eace71
#define IPV6_ARE_ADDR_EQUAL(a, b) \
Packit eace71
	(memcmp((char *)a, (char *)b, sizeof(struct ipv6_addr)) == 0)
Packit eace71
Packit eace71
/* Unspecified IPv6 address */
Packit eace71
#define IPV6_IS_ADDR_UNSPECIFIED(a)	\
Packit eace71
	((((a)->addr[0]) == 0) &&	\
Packit eace71
	(((a)->addr[1]) == 0) &&	\
Packit eace71
	(((a)->addr[2]) == 0) &&	\
Packit eace71
	(((a)->addr[3]) == 0))
Packit eace71
Packit eace71
/* IPv6 Scope Values */
Packit eace71
#define IPV6_ADDR_SCOPE_INTFACELOCAL    0x01	/* Node-local scope */
Packit eace71
#define IPV6_ADDR_SCOPE_LINKLOCAL       0x02	/* Link-local scope */
Packit eace71
#define IPV6_ADDR_SCOPE_SITELOCAL       0x05	/* Site-local scope */
Packit eace71
#define IPV6_ADDR_SCOPE_ORGLOCAL        0x08	/* Organization-local scope */
Packit eace71
#define IPV6_ADDR_SCOPE_GLOBAL          0x0e	/* Global scope */
Packit eace71
Packit eace71
/* Link-local Unicast : 10-bits much be 1111111010b --> 0xfe80. */
Packit eace71
#define IPV6_IS_ADDR_LINKLOCAL(a)        \
Packit eace71
	(((a)->addr8[0] == 0xfe) && (((a)->addr8[1] & 0xc0) == 0x80))
Packit eace71
Packit eace71
/* Site-local Unicast : 10-bits much be 1111111011b --> 0xfec0. */
Packit eace71
#define IPV6_IS_ADDR_SITELOCAL(a)        \
Packit eace71
	(((a)->addr8[0] == 0xfe) && (((a)->addr8[1] & 0xc0) == 0xc0))
Packit eace71
Packit eace71
/* Multicast : 10bits much be 11111111b. Next 4 bits is flags | 4-bit scope  */
Packit eace71
#define IPV6_IS_ADDR_MULTICAST(a)	((a)->addr8[0] == 0xff)
Packit eace71
Packit eace71
#define IPV6_ADDR_MC_SCOPE(a)		((a)->addr8[1] & 0x0f)
Packit eace71
Packit eace71
/* Multicast Scope */
Packit eace71
Packit eace71
struct eth_hdr {
Packit eace71
	struct mac_address dest_mac;
Packit eace71
	struct mac_address src_mac;
Packit eace71
	u16_t len_type;
Packit eace71
};
Packit eace71
Packit eace71
struct ipv6_hdr {
Packit eace71
	union {
Packit eace71
		struct {
Packit eace71
			u32_t ipv6_flow;	/* Version (4-bit) |
Packit eace71
						   Traffic Class (8-bit) |
Packit eace71
						   Flow ID (20-bit) */
Packit eace71
			u16_t ipv6_plen;	/* Payload length */
Packit eace71
			u8_t ipv6_nxt_hdr;	/* Next Header    */
Packit eace71
			u8_t ipv6_hop_limit;	/* hop limit */
Packit eace71
		} ipv6_dw1;
Packit eace71
Packit eace71
		u8_t ipv6_version_fc;	/* 4 bits version, top 4 bits class */
Packit eace71
	} ipv6_ctrl;
Packit eace71
Packit eace71
	struct ipv6_addr ipv6_src;	/* Source address */
Packit eace71
	struct ipv6_addr ipv6_dst;	/* Destination address */
Packit eace71
};
Packit eace71
Packit eace71
#define ipv6_version_fc		ipv6_ctrl.ipv6_version_fc
Packit eace71
#define ipv6_flow		ipv6_ctrl.ipv6_dw1.ipv6_flow
Packit eace71
#define ipv6_plen		ipv6_ctrl.ipv6_dw1.ipv6_plen
Packit eace71
#define ipv6_nxt_hdr		ipv6_ctrl.ipv6_dw1.ipv6_nxt_hdr
Packit eace71
#define ipv6_hop_limit		ipv6_ctrl.ipv6_dw1.ipv6_hop_limit
Packit eace71
Packit eace71
#define IPV6_VERSION		0x60
Packit eace71
#define IPV6_VERSION_MASK	0xf0
Packit eace71
#define IPV6_HOP_LIMIT		64
Packit eace71
Packit eace71
/* Length of the IP header with no next header */
Packit eace71
#define IPV6_HEADER_LEN		sizeof(struct ipv6_hdr)
Packit eace71
Packit eace71
#ifdef BIG_ENDIAN
Packit eace71
#define IPV6_FLOWINFO_MASK	0x0fffffff	/* flow info (28 bits) */
Packit eace71
#define IPV6_FLOWLABEL_MASK	0x000fffff	/* flow label (20 bits) */
Packit eace71
#else /* LITTLE_ENDIAN */
Packit eace71
#define IPV6_FLOWINFO_MASK	0xffffff0f	/* flow info (28 bits) */
Packit eace71
#define IPV6_FLOWLABEL_MASK	0xffff0f00	/* flow label (20 bits) */
Packit eace71
#endif
Packit eace71
Packit eace71
struct packet_ipv6 {
Packit eace71
	struct mac_address dest_mac;
Packit eace71
	struct mac_address src_mac;
Packit eace71
	u16_t len_type;
Packit eace71
	struct ipv6_hdr ipv6;
Packit eace71
	union {
Packit eace71
		struct udp_hdr udp;
Packit eace71
	} layer4_prot;
Packit eace71
};
Packit eace71
Packit eace71
struct packet_ipv6_vlan {
Packit eace71
	struct mac_address dest_mac;
Packit eace71
	struct mac_address src_mac;
Packit eace71
	u16_t len_type;
Packit eace71
	u16_t vlan_id;
Packit eace71
	struct ipv6_hdr ipv6;
Packit eace71
	union {
Packit eace71
		struct udp_hdr udp;
Packit eace71
	} layer4_prot;
Packit eace71
};
Packit eace71
Packit eace71
struct ipv6_arp_entry {
Packit eace71
	struct ipv6_addr ip_addr;
Packit eace71
	struct mac_address mac_addr;
Packit eace71
	u8_t time;
Packit eace71
};
Packit eace71
Packit eace71
#define IPV6_NUM_OF_ADDRESS_ENTRY  4
Packit eace71
Packit eace71
struct ipv6_prefix_entry {
Packit eace71
	struct ipv6_prefix_entry *next;
Packit eace71
	struct ipv6_addr ip_addr;
Packit eace71
	u8_t prefix_len;
Packit eace71
};
Packit eace71
Packit eace71
struct ipv6_addr_entry {
Packit eace71
	struct ipv6_addr ip_addr;
Packit eace71
	u8_t prefix_len;
Packit eace71
};
Packit eace71
Packit eace71
struct ipv6_context {
Packit eace71
	u16_t flags;
Packit eace71
#define IPV6_FLAGS_MANAGED_ADDR_CONFIG    (1 << 0)
Packit eace71
#define IPV6_FLAGS_OTHER_STATEFUL_CONFIG  (1 << 1)
Packit eace71
#define IPV6_FLAGS_ROUTER_ADV_RECEIVED    (1 << 2)
Packit eace71
#define IPV6_FLAGS_DISABLE_DHCPV6         (1 << 3)
Packit eace71
Packit eace71
	struct mac_address mac_addr;
Packit eace71
	struct ipv6_addr link_local_addr;
Packit eace71
	struct ipv6_addr link_local_multi;
Packit eace71
	struct ipv6_addr multi;	/* For Static IPv6 only */
Packit eace71
	struct ipv6_addr multi_dest;	/* For Static IPv6 only */
Packit eace71
	struct ipv6_addr default_router;
Packit eace71
	struct ipv6_prefix_entry *addr_list;
Packit eace71
	u8_t hop_limit;
Packit eace71
#define UIP_ARPTAB_SIZE 16
Packit eace71
Packit eace71
	struct uip_stack *ustack;
Packit eace71
#define MAX_MCADDR_TABLE 5
Packit eace71
	struct mac_address mc_addr[MAX_MCADDR_TABLE];
Packit eace71
	u8_t arptime;
Packit eace71
	struct ipv6_arp_entry ipv6_arp_table[UIP_ARPTAB_SIZE];
Packit eace71
	struct ipv6_prefix_entry ipv6_prefix_table[IPV6_NUM_OF_ADDRESS_ENTRY];
Packit eace71
Packit eace71
	/* VLAN support */
Packit eace71
Packit eace71
	void *dhcpv6_context;
Packit eace71
};
Packit eace71
Packit eace71
#define ISCSI_FLAGS_DHCP_TCPIP_CONFIG (1<<0)
Packit eace71
#define ISCSI_FLAGS_DHCP_ISCSI_CONFIG (1<<1)
Packit eace71
Packit eace71
#define IPV6_MAX_ROUTER_SOL_DELAY     4
Packit eace71
#define IPV6_MAX_ROUTER_SOL_RETRY     3
Packit eace71
Packit eace71
#define DHCPV6_CLIENT_PORT    546
Packit eace71
#define DHCPV6_SERVER_PORT    547
Packit eace71
Packit eace71
/* Function prototype */
Packit eace71
void ipv6_init(struct ndpc_state *ndp, int cfg);
Packit eace71
int ipv6_autoconfig(struct ipv6_context *context);
Packit eace71
int ipv6_discover_address(struct ipv6_context *context);
Packit eace71
struct ipv6_addr *ipv6_our_address(struct ipv6_context *context);
Packit eace71
int ipv6_ip_in_arp_table(struct ipv6_context *context,
Packit eace71
			 struct ipv6_addr *ipv6_addr,
Packit eace71
			 struct mac_address *mac_addr);
Packit eace71
void ipv6_arp_timer(struct ipv6_context *context);
Packit eace71
void ipv6_arp_out(struct ipv6_context *context, int *uip_len);
Packit eace71
int ipv6_add_prefix_entry(struct ipv6_context *context,
Packit eace71
			  struct ipv6_addr *ip_addr, u8_t prefix_len);
Packit eace71
void ipv6_set_ip_params(struct ipv6_context *context,
Packit eace71
			struct ipv6_addr *src_ip, u8_t prefix_len,
Packit eace71
			struct ipv6_addr *default_gateway,
Packit eace71
			struct ipv6_addr *linklocal);
Packit eace71
void ipv6_set_host_addr(struct ipv6_context *context, struct ipv6_addr *src_ip);
Packit eace71
int ipv6_get_default_router_ip_addrs(struct ipv6_context *context,
Packit eace71
				     struct ipv6_addr *ip_addr);
Packit eace71
struct mac_address *ipv6_get_link_addr(struct ipv6_context *context);
Packit eace71
u16_t ipv6_do_stateful_dhcpv6(struct ipv6_context *context, u32_t flags);
Packit eace71
void ipv6_add_solit_node_address(struct ipv6_context *context,
Packit eace71
				 struct ipv6_addr *ip_addr);
Packit eace71
int ipv6_get_source_ip_addrs(struct ipv6_context *context,
Packit eace71
			     struct ipv6_addr_entry *addr_list);
Packit eace71
void ipv6_cfg_link_local_addr(struct ipv6_context *context,
Packit eace71
			      struct ipv6_addr *ip_addr);
Packit eace71
void ipv6_disable_dhcpv6(struct ipv6_context *context);
Packit eace71
int ipv6_send_nd_solicited_packet(struct ipv6_context *context,
Packit eace71
				  struct eth_hdr *eth, struct ipv6_hdr *ipv6);
Packit eace71
int ipv6_is_it_our_link_local_address(struct ipv6_context *context,
Packit eace71
				      struct ipv6_addr *ip_addr);
Packit eace71
void ipv6_mc_init_dest_mac(struct eth_hdr *eth, struct ipv6_hdr *ipv6);
Packit eace71
struct ipv6_addr *ipv6_find_longest_match(struct ipv6_context *context,
Packit eace71
					  struct ipv6_addr *ip_addr);
Packit eace71
Packit eace71
#endif /* __IPV6_H__ */