xref: /freebsd/usr.sbin/rtadvd/rtadvd.h (revision fe267a559009cbf34f9341666fe4d88a92c02d5e)
1 /*	$FreeBSD$	*/
2 /*	$KAME: rtadvd.h,v 1.26 2003/08/05 12:34:23 itojun Exp $	*/
3 
4 /*-
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Copyright (C) 1998 WIDE Project.
8  * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the project nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #define	ELM_MALLOC(p,error_action)					\
37 	do {								\
38 		p = malloc(sizeof(*p));					\
39 		if (p == NULL) {					\
40 			syslog(LOG_ERR, "<%s> malloc failed: %s",	\
41 			    __func__, strerror(errno));			\
42 			error_action;					\
43 		}							\
44 		memset(p, 0, sizeof(*p));				\
45 	} while(0)
46 
47 #define IN6ADDR_LINKLOCAL_ALLNODES_INIT				\
48 	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
49 	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
50 
51 #define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT			\
52 	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
53 	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
54 
55 #define IN6ADDR_SITELOCAL_ALLROUTERS_INIT			\
56 	{{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
57 	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
58 
59 extern struct sockaddr_in6 sin6_linklocal_allnodes;
60 extern struct sockaddr_in6 sin6_linklocal_allrouters;
61 extern struct sockaddr_in6 sin6_sitelocal_allrouters;
62 
63 /*
64  * RFC 3542 API deprecates IPV6_PKTINFO in favor of
65  * IPV6_RECVPKTINFO
66  */
67 #ifndef IPV6_RECVPKTINFO
68 #ifdef IPV6_PKTINFO
69 #define IPV6_RECVPKTINFO	IPV6_PKTINFO
70 #endif
71 #endif
72 
73 /*
74  * RFC 3542 API deprecates IPV6_HOPLIMIT in favor of
75  * IPV6_RECVHOPLIMIT
76  */
77 #ifndef IPV6_RECVHOPLIMIT
78 #ifdef IPV6_HOPLIMIT
79 #define IPV6_RECVHOPLIMIT	IPV6_HOPLIMIT
80 #endif
81 #endif
82 
83 /* protocol constants and default values */
84 #define DEF_MAXRTRADVINTERVAL 600
85 #define DEF_ADVLINKMTU 0
86 #define DEF_ADVREACHABLETIME 0
87 #define DEF_ADVRETRANSTIMER 0
88 #define DEF_ADVCURHOPLIMIT 64
89 #define DEF_ADVVALIDLIFETIME 2592000
90 #define DEF_ADVPREFERREDLIFETIME 604800
91 
92 #define MAXROUTERLIFETIME 9000
93 #define MIN_MAXINTERVAL 4
94 #define MAX_MAXINTERVAL 1800
95 #define MIN_MININTERVAL 3
96 #define MAXREACHABLETIME 3600000
97 
98 #define MAX_INITIAL_RTR_ADVERT_INTERVAL  16
99 #define MAX_INITIAL_RTR_ADVERTISEMENTS    3
100 #define MAX_FINAL_RTR_ADVERTISEMENTS      3
101 #define MIN_DELAY_BETWEEN_RAS             3
102 #define MAX_RA_DELAY_TIME                 500000 /* usec */
103 
104 #define PREFIX_FROM_KERNEL 1
105 #define PREFIX_FROM_CONFIG 2
106 #define PREFIX_FROM_DYNAMIC 3
107 
108 struct prefix {
109 	TAILQ_ENTRY(prefix)	pfx_next;
110 
111 	struct rainfo *pfx_rainfo;	/* back pointer to the interface */
112 	/*
113 	 * Expiration timer.  This is used when a prefix derived from
114 	 * the kernel is deleted.
115 	 */
116 	struct rtadvd_timer *pfx_timer;
117 
118 	uint32_t	pfx_validlifetime;	/* AdvValidLifetime */
119 	uint32_t       	pfx_vltimeexpire;	/* Expiration of vltime */
120 	uint32_t	pfx_preflifetime;	/* AdvPreferredLifetime */
121 	uint32_t	pfx_pltimeexpire;	/* Expiration of pltime */
122 	int		pfx_onlinkflg;		/* bool: AdvOnLinkFlag */
123 	int		pfx_autoconfflg;	/* bool: AdvAutonomousFlag */
124 	int		pfx_prefixlen;
125 	int		pfx_origin;		/* From kernel or config */
126 
127 	struct in6_addr	pfx_prefix;
128 };
129 
130 struct rtinfo {
131 	TAILQ_ENTRY(rtinfo)	rti_next;
132 
133 	uint32_t	rti_ltime;	/* route lifetime */
134 	int		rti_rtpref;	/* route preference */
135 	int		rti_prefixlen;
136 	struct in6_addr	rti_prefix;
137 };
138 
139 struct rdnss_addr {
140 	TAILQ_ENTRY(rdnss_addr)	ra_next;
141 
142 	struct in6_addr ra_dns;	/* DNS server entry */
143 };
144 
145 struct rdnss {
146 	TAILQ_ENTRY(rdnss) rd_next;
147 
148 	TAILQ_HEAD(, rdnss_addr) rd_list;	/* list of DNS servers */
149 	uint32_t rd_ltime;	/* number of seconds valid */
150 };
151 
152 /*
153  * The maximum length of a domain name in a DNS search list is calculated
154  * by a domain name + length fields per 63 octets + a zero octet at
155  * the tail and adding 8 octet boundary padding.
156  */
157 #define _DNAME_LABELENC_MAXLEN \
158 	(NI_MAXHOST + (NI_MAXHOST / 64 + 1) + 1)
159 
160 #define DNAME_LABELENC_MAXLEN \
161 	(_DNAME_LABELENC_MAXLEN + 8 - _DNAME_LABELENC_MAXLEN % 8)
162 
163 struct dnssl_addr {
164 	TAILQ_ENTRY(dnssl_addr)	da_next;
165 
166 	int da_len;				/* length of entry */
167 	char da_dom[DNAME_LABELENC_MAXLEN];	/* search domain name entry */
168 };
169 
170 struct dnssl {
171 	TAILQ_ENTRY(dnssl)	dn_next;
172 
173 	TAILQ_HEAD(, dnssl_addr) dn_list;	/* list of search domains */
174 	uint32_t dn_ltime;			/* number of seconds valid */
175 };
176 
177 struct soliciter {
178 	TAILQ_ENTRY(soliciter)	sol_next;
179 
180 	struct sockaddr_in6	sol_addr;
181 };
182 
183 struct	rainfo {
184 	/* pointer for list */
185 	TAILQ_ENTRY(rainfo)	rai_next;
186 
187 	/* interface information */
188 	struct ifinfo *rai_ifinfo;
189 
190 	int	rai_advlinkopt;		/* bool: whether include link-layer addr opt */
191 	int	rai_advifprefix;	/* bool: gather IF prefixes? */
192 
193 	/* Router configuration variables */
194 	uint16_t	rai_lifetime;		/* AdvDefaultLifetime */
195 	uint16_t	rai_maxinterval;	/* MaxRtrAdvInterval */
196 	uint16_t	rai_mininterval;	/* MinRtrAdvInterval */
197 	int 	rai_managedflg;		/* AdvManagedFlag */
198 	int	rai_otherflg;		/* AdvOtherConfigFlag */
199 
200 	int	rai_rtpref;		/* router preference */
201 	uint32_t	rai_linkmtu;		/* AdvLinkMTU */
202 	uint32_t	rai_reachabletime;	/* AdvReachableTime */
203 	uint32_t	rai_retranstimer;	/* AdvRetransTimer */
204 	uint8_t	rai_hoplimit;		/* AdvCurHopLimit */
205 
206 	TAILQ_HEAD(, prefix) rai_prefix;/* AdvPrefixList(link head) */
207 	int	rai_pfxs;		/* number of prefixes */
208 
209 	uint16_t	rai_clockskew;	/* used for consisitency check of lifetimes */
210 
211 	TAILQ_HEAD(, rdnss) rai_rdnss;	/* DNS server list */
212 	TAILQ_HEAD(, dnssl) rai_dnssl;	/* search domain list */
213 	TAILQ_HEAD(, rtinfo) rai_route;	/* route information option (link head) */
214 	int	rai_routes;		/* number of route information options */
215 	/* actual RA packet data and its length */
216 	size_t	rai_ra_datalen;
217 	char	*rai_ra_data;
218 
219 	/* info about soliciter */
220 	TAILQ_HEAD(, soliciter) rai_soliciter;	/* recent solication source */
221 };
222 
223 /* RA information list */
224 extern TAILQ_HEAD(railist_head_t, rainfo) railist;
225 
226 /*
227  * ifi_state:
228  *
229  *           (INIT)
230  *              |
231  *              | update_ifinfo()
232  *              | update_persist_ifinfo()
233  *              v
234  *         UNCONFIGURED
235  *               |  ^
236  *   loadconfig()|  |rm_ifinfo(), ra_output()
237  *      (MC join)|  |(MC leave)
238  *               |  |
239  *               |  |
240  *               v  |
241  *         TRANSITIVE
242  *               |  ^
243  *    ra_output()|  |getconfig()
244  *               |  |
245  *               |  |
246  *               |  |
247  *               v  |
248  *         CONFIGURED
249  *
250  *
251  */
252 #define	IFI_STATE_UNCONFIGURED	0
253 #define	IFI_STATE_CONFIGURED	1
254 #define	IFI_STATE_TRANSITIVE	2
255 
256 struct	ifinfo {
257 	TAILQ_ENTRY(ifinfo)	ifi_next;
258 
259 	uint16_t	ifi_state;
260 	uint16_t	ifi_persist;
261 	uint16_t	ifi_ifindex;
262 	char	ifi_ifname[IFNAMSIZ];
263 	uint8_t	ifi_type;
264 	uint16_t	ifi_flags;
265 	uint32_t	ifi_nd_flags;
266 	uint32_t	ifi_phymtu;
267 	struct sockaddr_dl	ifi_sdl;
268 
269 	struct rainfo	*ifi_rainfo;
270 	struct rainfo	*ifi_rainfo_trans;
271 	uint16_t	ifi_burstcount;
272 	uint32_t	ifi_burstinterval;
273 	struct rtadvd_timer	*ifi_ra_timer;
274 	/* timestamp when the latest RA was sent */
275 	struct timespec		ifi_ra_lastsent;
276 	uint16_t	ifi_rs_waitcount;
277 
278 	/* statistics */
279 	uint64_t ifi_raoutput;		/* # of RAs sent */
280 	uint64_t ifi_rainput;		/* # of RAs received */
281 	uint64_t ifi_rainconsistent;	/* # of inconsistent recv'd RAs  */
282 	uint64_t ifi_rsinput;		/* # of RSs received */
283 };
284 
285 /* Interface list */
286 extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
287 
288 extern char *mcastif;
289 
290 struct rtadvd_timer	*ra_timeout(void *);
291 void			ra_timer_update(void *, struct timespec *);
292 void			ra_output(struct ifinfo *);
293 
294 int			prefix_match(struct in6_addr *, int,
295 			    struct in6_addr *, int);
296 struct ifinfo		*if_indextoifinfo(int);
297 struct prefix		*find_prefix(struct rainfo *,
298 			    struct in6_addr *, int);
299 void			rtadvd_set_reload(int);
300 void			rtadvd_set_shutdown(int);
301