rtadvd.h revision 330897
1/*	$FreeBSD: stable/11/usr.sbin/rtadvd/rtadvd.h 330897 2018-03-14 03:19:51Z eadler $	*/
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
59extern struct sockaddr_in6 sin6_linklocal_allnodes;
60extern struct sockaddr_in6 sin6_linklocal_allrouters;
61extern 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
108struct 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
130struct 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
139struct rdnss_addr {
140	TAILQ_ENTRY(rdnss_addr)	ra_next;
141
142	struct in6_addr ra_dns;	/* DNS server entry */
143};
144
145struct 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
163struct 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
170struct 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
177struct soliciter {
178	TAILQ_ENTRY(soliciter)	sol_next;
179
180	struct sockaddr_in6	sol_addr;
181};
182
183struct	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 */
224extern 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
256struct	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 */
286extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
287
288extern char *mcastif;
289
290struct rtadvd_timer	*ra_timeout(void *);
291void			ra_timer_update(void *, struct timespec *);
292void			ra_output(struct ifinfo *);
293
294int			prefix_match(struct in6_addr *, int,
295			    struct in6_addr *, int);
296struct ifinfo		*if_indextoifinfo(int);
297struct prefix		*find_prefix(struct rainfo *,
298			    struct in6_addr *, int);
299void			rtadvd_set_reload(int);
300void			rtadvd_set_shutdown(int);
301