1*1cb875aeSCathy Zhou /*
2*1cb875aeSCathy Zhou  * CDDL HEADER START
3*1cb875aeSCathy Zhou  *
4*1cb875aeSCathy Zhou  * The contents of this file are subject to the terms of the
5*1cb875aeSCathy Zhou  * Common Development and Distribution License (the "License").
6*1cb875aeSCathy Zhou  * You may not use this file except in compliance with the License.
7*1cb875aeSCathy Zhou  *
8*1cb875aeSCathy Zhou  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1cb875aeSCathy Zhou  * or http://www.opensolaris.org/os/licensing.
10*1cb875aeSCathy Zhou  * See the License for the specific language governing permissions
11*1cb875aeSCathy Zhou  * and limitations under the License.
12*1cb875aeSCathy Zhou  *
13*1cb875aeSCathy Zhou  * When distributing Covered Code, include this CDDL HEADER in each
14*1cb875aeSCathy Zhou  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1cb875aeSCathy Zhou  * If applicable, add the following below this CDDL HEADER, with the
16*1cb875aeSCathy Zhou  * fields enclosed by brackets "[]" replaced with your own identifying
17*1cb875aeSCathy Zhou  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1cb875aeSCathy Zhou  *
19*1cb875aeSCathy Zhou  * CDDL HEADER END
20*1cb875aeSCathy Zhou  */
21*1cb875aeSCathy Zhou 
22*1cb875aeSCathy Zhou /*
23*1cb875aeSCathy Zhou  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*1cb875aeSCathy Zhou  * Use is subject to license terms.
25*1cb875aeSCathy Zhou  */
26*1cb875aeSCathy Zhou 
27*1cb875aeSCathy Zhou #ifndef	_VRRPD_IMPL_H
28*1cb875aeSCathy Zhou #define	_VRRPD_IMPL_H
29*1cb875aeSCathy Zhou 
30*1cb875aeSCathy Zhou #include <sys/queue.h>
31*1cb875aeSCathy Zhou #include <libinetutil.h>
32*1cb875aeSCathy Zhou #include <libvrrpadm.h>
33*1cb875aeSCathy Zhou 
34*1cb875aeSCathy Zhou #ifdef __cplusplus
35*1cb875aeSCathy Zhou extern "C" {
36*1cb875aeSCathy Zhou #endif
37*1cb875aeSCathy Zhou 
38*1cb875aeSCathy Zhou /*
39*1cb875aeSCathy Zhou  * Internal data structs to store VRRP instance configuration information
40*1cb875aeSCathy Zhou  * and run-time state information.
41*1cb875aeSCathy Zhou  */
42*1cb875aeSCathy Zhou typedef useconds_t	vrrp_timeout_t;
43*1cb875aeSCathy Zhou 
44*1cb875aeSCathy Zhou typedef struct vrrp_vr_s {
45*1cb875aeSCathy Zhou 	vrrp_vr_conf_t		vvr_conf;
46*1cb875aeSCathy Zhou 	uint32_t		vvr_master_adver_int;
47*1cb875aeSCathy Zhou 	char			vvr_vnic[MAXLINKNAMELEN];
48*1cb875aeSCathy Zhou 	struct vrrp_intf_s	*vvr_pif;
49*1cb875aeSCathy Zhou 	struct vrrp_intf_s	*vvr_vif;
50*1cb875aeSCathy Zhou 
51*1cb875aeSCathy Zhou 	/*
52*1cb875aeSCathy Zhou 	 * Timer reused in master/backup state:
53*1cb875aeSCathy Zhou 	 *   Master: The Advertisement_Interval (Adver_Timer)
54*1cb875aeSCathy Zhou 	 *   Backup: The Master_Down_Intervel (Master_Down_timer)
55*1cb875aeSCathy Zhou 	 */
56*1cb875aeSCathy Zhou 	vrrp_timeout_t		vvr_timeout;
57*1cb875aeSCathy Zhou 	iu_timer_id_t		vvr_timer_id;
58*1cb875aeSCathy Zhou 
59*1cb875aeSCathy Zhou 	/*
60*1cb875aeSCathy Zhou 	 * Peer information, got from the last adv message received
61*1cb875aeSCathy Zhou 	 */
62*1cb875aeSCathy Zhou 	vrrp_peer_t		vvr_peer;
63*1cb875aeSCathy Zhou #define	vvr_peer_addr		vvr_peer.vp_addr
64*1cb875aeSCathy Zhou #define	vvr_peer_time		vvr_peer.vp_time
65*1cb875aeSCathy Zhou #define	vvr_peer_prio		vvr_peer.vp_prio
66*1cb875aeSCathy Zhou #define	vvr_peer_adver_int	vvr_peer.vp_adver_int
67*1cb875aeSCathy Zhou 
68*1cb875aeSCathy Zhou 	vrrp_stateinfo_t	vvr_sinfo;
69*1cb875aeSCathy Zhou #define	vvr_state		vvr_sinfo.vs_state
70*1cb875aeSCathy Zhou #define	vvr_prev_state		vvr_sinfo.vs_prev_state
71*1cb875aeSCathy Zhou #define	vvr_st_time		vvr_sinfo.vs_st_time
72*1cb875aeSCathy Zhou 
73*1cb875aeSCathy Zhou 	/*
74*1cb875aeSCathy Zhou 	 * Record the reason why the virtual router stays at the INIT
75*1cb875aeSCathy Zhou 	 * state, for the diagnose purpose.
76*1cb875aeSCathy Zhou 	 */
77*1cb875aeSCathy Zhou 	vrrp_err_t		vvr_err;
78*1cb875aeSCathy Zhou 	TAILQ_ENTRY(vrrp_vr_s)	vvr_next;
79*1cb875aeSCathy Zhou } vrrp_vr_t;
80*1cb875aeSCathy Zhou 
81*1cb875aeSCathy Zhou /* IP address/interface cache state flags */
82*1cb875aeSCathy Zhou typedef enum {
83*1cb875aeSCathy Zhou 	NODE_STATE_NONE		= 0,
84*1cb875aeSCathy Zhou 	NODE_STATE_STALE	= 1,
85*1cb875aeSCathy Zhou 	NODE_STATE_NEW		= 2
86*1cb875aeSCathy Zhou } node_state_t;
87*1cb875aeSCathy Zhou 
88*1cb875aeSCathy Zhou /*
89*1cb875aeSCathy Zhou  * The ifindex is get by the SIOCGLIFINDEX ioctl, easy to make it part of
90*1cb875aeSCathy Zhou  * vrrp_ip_t instead of vrrp_intf_t
91*1cb875aeSCathy Zhou  */
92*1cb875aeSCathy Zhou typedef struct vrrp_ip_s {
93*1cb875aeSCathy Zhou 	char			vip_lifname[LIFNAMSIZ];
94*1cb875aeSCathy Zhou 	vrrp_addr_t		vip_addr;
95*1cb875aeSCathy Zhou 	uint64_t		vip_flags;
96*1cb875aeSCathy Zhou 	node_state_t		vip_state;
97*1cb875aeSCathy Zhou 	TAILQ_ENTRY(vrrp_ip_s)	vip_next;
98*1cb875aeSCathy Zhou } vrrp_ip_t;
99*1cb875aeSCathy Zhou 
100*1cb875aeSCathy Zhou /*
101*1cb875aeSCathy Zhou  * Used for primary interfaces
102*1cb875aeSCathy Zhou  */
103*1cb875aeSCathy Zhou typedef struct vrrp_primary_ifinfo {
104*1cb875aeSCathy Zhou 	uint32_t		vpii_nvr;	/* numbers of virtual routers */
105*1cb875aeSCathy Zhou 	vrrp_ip_t		*vpii_pip;	/* primary IP address */
106*1cb875aeSCathy Zhou 	iu_event_id_t		vpii_eid;	/* event id of RX socket */
107*1cb875aeSCathy Zhou 						/* non-zero on the primary if */
108*1cb875aeSCathy Zhou } vrrp_primary_ifinfo_t;
109*1cb875aeSCathy Zhou 
110*1cb875aeSCathy Zhou /*
111*1cb875aeSCathy Zhou  * Used for virtual interfaces
112*1cb875aeSCathy Zhou  */
113*1cb875aeSCathy Zhou typedef struct vrrp_virtual_ifinfo {
114*1cb875aeSCathy Zhou 	/*
115*1cb875aeSCathy Zhou 	 * the state of the VRRP router, used to determine the up/down
116*1cb875aeSCathy Zhou 	 * state of the virtual IP addresses
117*1cb875aeSCathy Zhou 	 */
118*1cb875aeSCathy Zhou 	vrrp_state_t	vvii_state;
119*1cb875aeSCathy Zhou } vrrp_virtual_ifinfo_t;
120*1cb875aeSCathy Zhou 
121*1cb875aeSCathy Zhou /*
122*1cb875aeSCathy Zhou  * VRRP interface structure
123*1cb875aeSCathy Zhou  *
124*1cb875aeSCathy Zhou  * An interface is either the primary interface which owns the primary IP
125*1cb875aeSCathy Zhou  * address or a VNIC interface which owns the virtual IP addresses.
126*1cb875aeSCathy Zhou  * As the primary interface, it can be shared by several VRRP routers.
127*1cb875aeSCathy Zhou  */
128*1cb875aeSCathy Zhou typedef struct vrrp_intf_s {
129*1cb875aeSCathy Zhou 	char			vvi_ifname[LIFNAMSIZ];
130*1cb875aeSCathy Zhou 	int			vvi_af;		/* address family */
131*1cb875aeSCathy Zhou 	node_state_t		vvi_state;
132*1cb875aeSCathy Zhou 	uint32_t		vvi_ifindex;	/* interface index */
133*1cb875aeSCathy Zhou 	TAILQ_HEAD(, vrrp_ip_s)	vvi_iplist;	/* IP adddress list */
134*1cb875aeSCathy Zhou 	TAILQ_ENTRY(vrrp_intf_s) vvi_next;
135*1cb875aeSCathy Zhou 
136*1cb875aeSCathy Zhou 	/*
137*1cb875aeSCathy Zhou 	 * Socket fd.
138*1cb875aeSCathy Zhou 	 * - physical interfaces: used to receive the VRRP packet, and shared
139*1cb875aeSCathy Zhou 	 *   by all virtual routers on this physical interface.
140*1cb875aeSCathy Zhou 	 * - vnic interfaces: used to send the VRRP packet.
141*1cb875aeSCathy Zhou 	 */
142*1cb875aeSCathy Zhou 	int			vvi_sockfd;
143*1cb875aeSCathy Zhou 
144*1cb875aeSCathy Zhou 	vrrp_primary_ifinfo_t	pifinfo;	/* Primary interface info */
145*1cb875aeSCathy Zhou 	vrrp_virtual_ifinfo_t	vifinfo;	/* VNIC interface info */
146*1cb875aeSCathy Zhou #define	vvi_nvr		pifinfo.vpii_nvr
147*1cb875aeSCathy Zhou #define	vvi_pip		pifinfo.vpii_pip
148*1cb875aeSCathy Zhou #define	vvi_eid		pifinfo.vpii_eid
149*1cb875aeSCathy Zhou #define	vvi_vr_state	vifinfo.vvii_state
150*1cb875aeSCathy Zhou } vrrp_intf_t;
151*1cb875aeSCathy Zhou 
152*1cb875aeSCathy Zhou #define	IS_PRIMARY_INTF(intf) \
153*1cb875aeSCathy Zhou 	(((intf)->vvi_sockfd >= 0) && ((intf)->vvi_eid != -1))
154*1cb875aeSCathy Zhou 
155*1cb875aeSCathy Zhou #define	IS_VIRTUAL_INTF(intf) \
156*1cb875aeSCathy Zhou 	(((intf)->vvi_sockfd >= 0) && ((intf)->vvi_eid == -1))
157*1cb875aeSCathy Zhou 
158*1cb875aeSCathy Zhou #define	VRRP_ERR	0	/* error message */
159*1cb875aeSCathy Zhou #define	VRRP_WARNING	1
160*1cb875aeSCathy Zhou #define	VRRP_NOTICE	2
161*1cb875aeSCathy Zhou #define	VRRP_INFO	3
162*1cb875aeSCathy Zhou #define	VRRP_DBG0	4	/* debug message, only function calls */
163*1cb875aeSCathy Zhou #define	VRRP_DBG1	5	/* detailed debug message */
164*1cb875aeSCathy Zhou 
165*1cb875aeSCathy Zhou /*
166*1cb875aeSCathy Zhou  * The primary IP address must be brought up; further, in the case of IPv6,
167*1cb875aeSCathy Zhou  * the link-local IP address is used as the primary IP address.
168*1cb875aeSCathy Zhou  */
169*1cb875aeSCathy Zhou #define	QUALIFY_PRIMARY_ADDR(intf, ip)					\
170*1cb875aeSCathy Zhou 	(((ip)->vip_flags & IFF_UP) && ((intf)->vvi_af != AF_INET6 ||	\
171*1cb875aeSCathy Zhou 	IN6_IS_ADDR_LINKLOCAL(&(ip)->vip_addr.in6.sin6_addr)))
172*1cb875aeSCathy Zhou 
173*1cb875aeSCathy Zhou 
174*1cb875aeSCathy Zhou #ifdef __cplusplus
175*1cb875aeSCathy Zhou }
176*1cb875aeSCathy Zhou #endif
177*1cb875aeSCathy Zhou 
178*1cb875aeSCathy Zhou #endif	/* _VRRPD_IMPL_H */