rtadvd - Import newer rtadvd, add rtadvctl from FreeBSD-10
[dragonfly.git] / usr.sbin / rtadvd / rtadvd.h
1 /*      $FreeBSD: stable/10/usr.sbin/rtadvd/rtadvd.h 253970 2013-08-05 20:13:02Z hrs $  */
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);