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