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  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_NDPD_TABLES_H
27 #define	_NDPD_TABLES_H
28 
29 #ifdef	__cplusplus
30 extern "C" {
31 #endif
32 
33 #include <ndpd.h>
34 #include <libipadm.h>
35 
36 enum adv_states { NO_ADV = 0, REG_ADV, INIT_ADV, SOLICIT_ADV, FINAL_ADV };
37 enum adv_events { ADV_OFF, START_INIT_ADV, START_FINAL_ADV, RECEIVED_SOLICIT,
38 			ADV_TIMER };
39 
40 enum solicit_states { NO_SOLICIT = 0, INIT_SOLICIT, DONE_SOLICIT };
41 enum solicit_events { SOLICIT_OFF, START_INIT_SOLICIT, SOL_TIMER,
42 			SOLICIT_DONE, RESTART_INIT_SOLICIT };
43 
44 /*
45  * A doubly linked list of all physical interfaces that each contain a
46  * doubly linked list of prefixes (i.e. logical interfaces) and default
47  * routers.
48  */
49 struct phyint {
50 	struct phyint	*pi_next;
51 	struct phyint	*pi_prev;
52 	struct prefix	*pi_prefix_list;	/* Doubly linked prefixes */
53 	struct router	*pi_router_list;	/* Doubly linked routers */
54 	struct adv_prefix *pi_adv_prefix_list;	/* Doubly linked adv.prefixes */
55 
56 	uint_t		pi_index;		/* Identifier > 0 */
57 	char		pi_name[LIFNAMSIZ];	/* Used to identify it */
58 	int		pi_sock;		/* For sending and receiving */
59 	struct in6_addr	pi_ifaddr;		/* Local address */
60 	uint64_t		pi_flags;		/* IFF_* flags */
61 	uint_t		pi_mtu;			/* From SIOCGLIFMTU */
62 	struct in6_addr pi_token;
63 	uint_t		pi_token_length;
64 	boolean_t	pi_stateless;
65 	boolean_t	pi_stateful;
66 	struct in6_addr	pi_tmp_token;		/* For RFC3041 addrs */
67 	struct in6_addr	pi_dst_token;		/* For POINTOPOINT */
68 
69 	uint_t		pi_state;		/* PI_* below */
70 	uint_t		pi_kernel_state;	/* PI_* below */
71 	uint_t		pi_num_k_routers;	/* # routers in kernel */
72 	uint_t		pi_reach_time_since_random;	/* In milliseconds */
73 
74 	/* Applies if pi_AdvSendAdvertisements */
75 	uint_t		pi_adv_time_left;	/* In milliseconds */
76 	uint_t		pi_adv_time_since_sent;	/* In milliseconds */
77 	enum adv_states	pi_adv_state;
78 	uint_t		pi_adv_count;
79 
80 	/* Applies if not pi_AdvSendAdvertisements */
81 	uint_t		pi_sol_time_left;	/* In milliseconds */
82 	enum solicit_states pi_sol_state;
83 	uint_t		pi_sol_count;
84 
85 	/* Interface specific configurable variables */
86 	struct confvar	pi_config[I_IFSIZE];
87 #define	pi_DupAddrDetectTransmits pi_config[I_DupAddrDetectTransmits].cf_value
88 #define	pi_AdvSendAdvertisements pi_config[I_AdvSendAdvertisements].cf_value
89 #define	pi_MaxRtrAdvInterval	pi_config[I_MaxRtrAdvInterval].cf_value
90 #define	pi_MinRtrAdvInterval	pi_config[I_MinRtrAdvInterval].cf_value
91 #define	pi_AdvManagedFlag	pi_config[I_AdvManagedFlag].cf_value
92 #define	pi_AdvOtherConfigFlag	pi_config[I_AdvOtherConfigFlag].cf_value
93 #define	pi_AdvLinkMTU		pi_config[I_AdvLinkMTU].cf_value
94 #define	pi_AdvReachableTime	pi_config[I_AdvReachableTime].cf_value
95 #define	pi_AdvRetransTimer	pi_config[I_AdvRetransTimer].cf_value
96 #define	pi_AdvCurHopLimit	pi_config[I_AdvCurHopLimit].cf_value
97 #define	pi_AdvDefaultLifetime	pi_config[I_AdvDefaultLifetime].cf_value
98 #define	pi_StatelessAddrConf	pi_config[I_StatelessAddrConf].cf_value
99 #define	pi_TmpAddrsEnabled	pi_config[I_TmpAddrsEnabled].cf_value
100 #define	pi_TmpValidLifetime	pi_config[I_TmpValidLifetime].cf_value
101 #define	pi_TmpPreferredLifetime	pi_config[I_TmpPreferredLifetime].cf_value
102 #define	pi_TmpRegenAdvance	pi_config[I_TmpRegenAdvance].cf_value
103 #define	pi_TmpMaxDesyncFactor	pi_config[I_TmpMaxDesyncFactor].cf_value
104 #define	pi_StatefulAddrConf	pi_config[I_StatefulAddrConf].cf_value
105 
106 	/* Recorded variables for RFC3041 addresses */
107 	uint_t		pi_TmpDesyncFactor;		/* In milliseconds */
108 	uint_t		pi_TmpRegenCountdown;		/* In milliseconds */
109 
110 	/* Recorded variables on node/host */
111 	uint_t		pi_LinkMTU;
112 	uint_t		pi_CurHopLimit;
113 	uint_t		pi_BaseReachableTime;		/* In milliseconds */
114 	uint_t		pi_ReachableTime;		/* In milliseconds */
115 	/*
116 	 * The above value should be a uniformly-distributed random
117 	 * value between ND_MIN_RANDOM_FACTOR and
118 	 * ND_MAX_RANDOM_FACTOR times BaseReachableTime
119 	 * milliseconds.  A new random value should be
120 	 * calculated when BaseReachableTime changes (due to
121 	 * Router Advertisements) or at least every few hours
122 	 * even if no Router Advertisements are received.
123 	 * Tracked using pi_each_time_since_random.
124 	 */
125 	uint_t		pi_RetransTimer;	/* In milliseconds */
126 
127 	uint_t		pi_ra_flags;	/* Detect when to start DHCP */
128 	boolean_t	pi_autoconf;	/* Enable/Disable autoconfiguration */
129 	boolean_t	pi_default_token;	/* Use default token */
130 	char		pi_ipadm_aobjname[IPADM_AOBJSIZ];
131 };
132 
133 /*
134  * pi_state/pr_kernel_state values
135  */
136 #define	PI_PRESENT		0x01
137 #define	PI_JOINED_ALLNODES	0x02	/* allnodes multicast joined */
138 #define	PI_JOINED_ALLROUTERS	0x04	/* allrouters multicast joined */
139 
140 /*
141  * Prefix configuration variable indices
142  */
143 #define	I_AdvValidLifetime	0	/* In seconds */
144 #define	I_AdvOnLinkFlag		1
145 #define	I_AdvPreferredLifetime	2	/* In seconds */
146 #define	I_AdvAutonomousFlag	3
147 #define	I_AdvValidExpiration	4	/* Seconds left */
148 #define	I_AdvPreferredExpiration 5	/* Seconds left */
149 #define	I_PREFIXSIZE		6	/* # of variables */
150 
151 /*
152  * A doubly-linked list of prefixes for onlink and addrconf.
153  * ("Prefixes" in this context are identical to logical interfaces.)
154  */
155 struct prefix {
156 	struct prefix	*pr_next;	/* Next prefix for this physical */
157 	struct prefix	*pr_prev;	/* Prev prefix for this physical */
158 	struct phyint	*pr_physical;	/* Back pointer */
159 
160 	struct in6_addr	pr_prefix;	/* Used to indentify prefix */
161 	uint_t		pr_prefix_len;	/* Num bits valid */
162 
163 	char		pr_name[LIFNAMSIZ];
164 	struct in6_addr	pr_address;
165 	uint64_t	pr_flags;	/* IFF_* flags */
166 
167 	uint_t		pr_state;	/* PR_ONLINK | PR_AUTO etc */
168 	uint_t		pr_kernel_state; /* PR_ONLINK | PR_AUTO etc */
169 	boolean_t	pr_in_use;	/* To detect removed prefixes */
170 
171 	/* Recorded variables on node/host */
172 	uint_t		pr_ValidLifetime;	/* In ms w/ 2 hour rule */
173 	uint_t		pr_PreferredLifetime;	/* In millseconds */
174 	uint_t		pr_OnLinkLifetime;	/* ms valid w/o 2 hour rule */
175 	boolean_t	pr_OnLinkFlag;
176 	boolean_t	pr_AutonomousFlag;
177 
178 	uint_t		pr_CreateTime;		/* tmpaddr creation time */
179 						/* in SECONDS */
180 	uint_t		pr_attempts;	/* attempts to configure */
181 };
182 
183 /*
184  * Flags used for pr_kernel_state and pr_state where the latter is
185  * user-level state.
186  */
187 #define	PR_ONLINK	0x01		/* On-link */
188 #define	PR_AUTO		0x02		/* Stateless addrconf */
189 #define	PR_DEPRECATED	0x04		/* Address is deprecated */
190 #define	PR_STATIC	0x08		/* Not created by ndpd */
191 
192 /*
193  * The sum of all possible state string lengths, plus terminating
194  * null character; if new states are added, this needs to be updated.
195  * Useful for passing an appropriately sized buffer to prefix_print_state().
196  *
197  * Current strings: "ONLINK ", "AUTO ", "DEPRECATED ", "STATIC ", "\n"
198  *                      7     +   5    +     11       +    7     +  1
199  */
200 #define	PREFIX_STATESTRLEN	31
201 
202 /* Prefix used for storing advertisement specific stuff */
203 struct adv_prefix {
204 	struct adv_prefix	*adv_pr_next;	/* Next prefix */
205 	struct adv_prefix	*adv_pr_prev;	/* Prev prefix */
206 	struct phyint		*adv_pr_physical;	/* Back pointer */
207 
208 	struct in6_addr		adv_pr_prefix;	/* Used to indentify prefix */
209 	uint_t			adv_pr_prefix_len;	/* Num bits valid */
210 
211 	/* Used when sending advertisements */
212 	struct confvar		adv_pr_config[I_PREFIXSIZE];
213 #define	adv_pr_AdvValidLifetime	adv_pr_config[I_AdvValidLifetime].cf_value
214 #define	adv_pr_AdvOnLinkFlag	adv_pr_config[I_AdvOnLinkFlag].cf_value
215 #define	adv_pr_AdvPreferredLifetime	\
216 			adv_pr_config[I_AdvPreferredLifetime].cf_value
217 #define	adv_pr_AdvAutonomousFlag	\
218 			adv_pr_config[I_AdvAutonomousFlag].cf_value
219 #define	adv_pr_AdvValidExpiration	\
220 			adv_pr_config[I_AdvValidExpiration].cf_value
221 #define	adv_pr_AdvPreferredExpiration	\
222 			adv_pr_config[I_AdvPreferredExpiration].cf_value
223 	/* The two below are set if the timers decrement in real time */
224 #define	adv_pr_AdvValidRealTime		\
225 			adv_pr_config[I_AdvValidExpiration].cf_notdefault
226 #define	adv_pr_AdvPreferredRealTime	\
227 			adv_pr_config[I_AdvPreferredExpiration].cf_notdefault
228 };
229 
230 /*
231  * Doubly-linked list of default routers on a phyint.
232  */
233 struct router {
234 	struct router	*dr_next;	/* Next router for this physical */
235 	struct router	*dr_prev;	/* Prev router for this physical */
236 	struct phyint	*dr_physical;	/* Back pointer */
237 
238 	struct in6_addr	dr_address;	/* Used to identify the router */
239 	uint_t		dr_lifetime;	/* In milliseconds */
240 	boolean_t	dr_inkernel;	/* Route added to kernel */
241 };
242 
243 /*
244  * Globals
245  */
246 extern struct phyint *phyints;
247 extern int num_of_phyints;
248 
249 /*
250  * Functions
251  */
252 extern uint_t		getcurrenttime(void);
253 
254 extern struct phyint	*phyint_lookup(char *name);
255 extern struct phyint	*phyint_lookup_on_index(uint_t ifindex);
256 extern struct phyint	*phyint_create(char *name);
257 extern int		phyint_init_from_k(struct phyint *pi);
258 extern void		phyint_delete(struct phyint *pi);
259 extern uint_t		phyint_timer(struct phyint *pi, uint_t elapsed);
260 extern void		phyint_print_all(void);
261 extern int		phyint_get_lla(struct phyint *pi, struct lifreq *lifrp);
262 extern void		phyint_reach_random(struct phyint *pi,
263 			    boolean_t set_needed);
264 extern void		phyint_cleanup(struct phyint *pi);
265 
266 extern boolean_t	tmptoken_create(struct phyint *pi);
267 extern void		tmptoken_delete(struct phyint *pi);
268 extern uint_t		tmptoken_timer(struct phyint *pi, uint_t elapsed);
269 extern boolean_t	token_equal(struct in6_addr t1, struct in6_addr t2,
270 			    int bits);
271 
272 extern struct prefix	*prefix_create(struct phyint *pi, struct in6_addr addr,
273 			    int addrlen, uint64_t flags);
274 extern struct prefix	*prefix_lookup_name(struct phyint *pi, char *name);
275 extern struct prefix	*prefix_lookup_addr_match(struct prefix *pr);
276 extern struct prefix	*prefix_create_name(struct phyint *pi, char *name);
277 extern int		prefix_init_from_k(struct prefix *pr);
278 extern void		prefix_delete(struct prefix *pr);
279 extern boolean_t	prefix_equal(struct in6_addr p1, struct in6_addr p2,
280 			    int bits);
281 extern void		prefix_update_dhcp(struct prefix *pr);
282 extern void		prefix_update_k(struct prefix *pr);
283 extern uint_t		prefix_timer(struct prefix *pr, uint_t elapsed);
284 extern uint_t		adv_prefix_timer(struct adv_prefix *adv_pr,
285 			    uint_t elapsed);
286 extern struct prefix	*prefix_lookup_addr(struct phyint *pi,
287 			    struct in6_addr prefix);
288 
289 extern struct adv_prefix *adv_prefix_lookup(struct phyint *pi,
290 			    struct in6_addr addr, int addrlen);
291 extern struct adv_prefix *adv_prefix_create(struct phyint *pi,
292 			    struct in6_addr addr, int addrlen);
293 
294 extern struct router	*router_lookup(struct phyint *pi, struct in6_addr addr);
295 extern struct router	*router_create(struct phyint *pi, struct in6_addr addr,
296 			    uint_t lifetime);
297 extern void		router_update_k(struct router *dr);
298 extern uint_t		router_timer(struct router *dr, uint_t elapsed);
299 
300 extern void	check_to_advertise(struct phyint *pi, enum adv_events event);
301 extern void	check_to_solicit(struct phyint *pi,
302 		    enum solicit_events event);
303 extern uint_t	advertise_event(struct phyint *pi, enum adv_events event,
304 		    uint_t elapsed);
305 extern uint_t	solicit_event(struct phyint *pi, enum solicit_events event,
306 		    uint_t elapsed);
307 
308 extern void	print_route_sol(char *str, struct phyint *pi,
309 		    struct nd_router_solicit *rs, int len,
310 		    struct sockaddr_in6 *addr);
311 extern void	print_route_adv(char *str, struct phyint *pi,
312 		    struct nd_router_advert *ra, int len,
313 		    struct sockaddr_in6 *addr);
314 extern void	print_iflist(struct confvar *confvar);
315 extern void	print_prefixlist(struct confvar *confvar);
316 
317 extern void	in_data(struct phyint *pi);
318 
319 extern void	start_dhcp(struct phyint *pi);
320 extern void	release_dhcp(struct phyint *pi);
321 
322 extern void	incoming_ra(struct phyint *pi, struct nd_router_advert *ra,
323 		    int len, struct sockaddr_in6 *from, boolean_t loopback);
324 
325 extern boolean_t incoming_prefix_addrconf_process(struct phyint *pi,
326 		    struct prefix *pr, uchar_t *opt,
327 		    struct sockaddr_in6 *from, boolean_t loopback,
328 		    boolean_t new_prefix);
329 
330 extern void	incoming_prefix_onlink_process(struct prefix *pr,
331 		    uchar_t *opt);
332 
333 extern void	check_autoconf_var_consistency(struct phyint *, boolean_t,
334     boolean_t);
335 extern void	prefix_update_ipadm_addrobj(struct prefix *pr, boolean_t add);
336 #ifdef	__cplusplus
337 }
338 #endif
339 
340 #endif	/* _NDPD_TABLES_H */
341