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