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