1 #include <fcntl.h> 2 #include <resolv.h> 3 #include <signal.h> 4 #include <arpa/inet.h> 5 #include <unistd.h> 6 #include <libgen.h> 7 #include <net/if.h> 8 #include <string.h> 9 #include <sys/stat.h> 10 #include <ctype.h> 11 12 #include <uci.h> 13 #include <uci_blob.h> 14 #include <libubox/utils.h> 15 #include <libubox/avl.h> 16 #include <libubox/avl-cmp.h> 17 #include <libubox/list.h> 18 #include <libubox/vlist.h> 19 20 #include "odhcpd.h" 21 #include "router.h" 22 #include "dhcpv6-pxe.h" 23 #include "dhcpv4.h" 24 #include "statefiles.h" 25 26 static struct blob_buf b; 27 28 static int lease_cfg_cmp(const void *k1, const void *k2, void *ptr); 29 static void lease_cfg_update(struct vlist_tree *tree, struct vlist_node *node_new, 30 struct vlist_node *node_old); 31 32 struct vlist_tree lease_cfgs = VLIST_TREE_INIT(lease_cfgs, lease_cfg_cmp, 33 lease_cfg_update, true, false); 34 35 AVL_TREE(interfaces, avl_strcmp, false, NULL); 36 struct config config = { 37 .enable_tz = true, 38 .main_dhcpv4 = false, 39 .dhcp_cb = NULL, 40 #ifdef WITH_UBUS 41 .use_ubus = true, 42 #else 43 .use_ubus = false, 44 #endif /* WITH_UBUS */ 45 .dhcp_statefile = NULL, 46 .dhcp_statedir_fd = -1, 47 .dhcp_hostsdir = NULL, 48 .dhcp_hostsdir_fd = -1, 49 .ra_piodir = NULL, 50 .ra_piodir_fd = -1, 51 .uci_cfgdir = NULL, 52 .log_level = LOG_WARNING, 53 .log_level_cmdline = false, 54 .log_syslog = true, 55 .default_duid = { 0 }, 56 .default_duid_len = 0, 57 }; 58 59 struct sys_conf sys_conf = { 60 .posix_tz = NULL, // "timezone" 61 .posix_tz_len = 0, 62 .tzdb_tz = NULL, // "zonename" 63 .tzdb_tz_len = 0, 64 }; 65 66 #define DHCPV4_POOL_LIMIT_DEFAULT 150 67 68 #define HOSTID_LEN_MIN 12 69 #define HOSTID_LEN_MAX 64 70 #define HOSTID_LEN_DEFAULT HOSTID_LEN_MIN 71 72 #define PD_MIN_LEN_MAX 64 73 #define PD_MIN_LEN_DEFAULT 62 74 75 enum { 76 IPV6_PXE_URL, 77 IPV6_PXE_ARCH, 78 IPV6_PXE_MAX 79 }; 80 81 static const struct blobmsg_policy ipv6_pxe_attrs[IPV6_PXE_MAX] = { 82 [IPV6_PXE_URL] = {.name = "url", .type = BLOBMSG_TYPE_STRING }, 83 [IPV6_PXE_ARCH] = {.name = "arch", .type = BLOBMSG_TYPE_INT32 }, 84 }; 85 86 const struct uci_blob_param_list ipv6_pxe_attr_list = { 87 .n_params = IPV6_PXE_MAX, 88 .params = ipv6_pxe_attrs, 89 }; 90 91 enum { 92 IFACE_ATTR_INTERFACE, 93 IFACE_ATTR_IFNAME, 94 IFACE_ATTR_NETWORKID, 95 IFACE_ATTR_DYNAMICDHCP, 96 IFACE_ATTR_LEASETIME, 97 IFACE_ATTR_DHCPV4_POOL_START, 98 IFACE_ATTR_DHCPV4_POOL_LIMIT, 99 IFACE_ATTR_MASTER, 100 IFACE_ATTR_UPSTREAM, 101 IFACE_ATTR_RA, 102 IFACE_ATTR_DHCPV4, 103 IFACE_ATTR_DHCPV6, 104 IFACE_ATTR_NDP, 105 IFACE_ATTR_ROUTER, 106 IFACE_ATTR_DNS, 107 IFACE_ATTR_DNR, 108 IFACE_ATTR_DNS_SERVICE, 109 IFACE_ATTR_DNS_DOMAIN_SEARCH, 110 IFACE_ATTR_DHCPV4_FORCERECONF, 111 IFACE_ATTR_DHCPV6_RAW, 112 IFACE_ATTR_DHCPV6_ASSIGNALL, 113 IFACE_ATTR_DHCPV6_PD_PREFERRED, 114 IFACE_ATTR_DHCPV6_PD, 115 IFACE_ATTR_DHCPV6_PD_MIN_LEN, 116 IFACE_ATTR_DHCPV6_NA, 117 IFACE_ATTR_DHCPV6_HOSTID_LEN, 118 IFACE_ATTR_RA_DEFAULT, 119 IFACE_ATTR_RA_FLAGS, 120 IFACE_ATTR_RA_SLAAC, 121 IFACE_ATTR_RA_OFFLINK, 122 IFACE_ATTR_RA_PREFERENCE, 123 IFACE_ATTR_RA_ADVROUTER, 124 IFACE_ATTR_RA_MININTERVAL, 125 IFACE_ATTR_RA_MAXINTERVAL, 126 IFACE_ATTR_RA_LIFETIME, 127 IFACE_ATTR_RA_REACHABLETIME, 128 IFACE_ATTR_RA_RETRANSTIME, 129 IFACE_ATTR_RA_HOPLIMIT, 130 IFACE_ATTR_RA_MTU, 131 IFACE_ATTR_RA_DNS, 132 IFACE_ATTR_RA_PREF64, 133 IFACE_ATTR_NDPROXY_ROUTING, 134 IFACE_ATTR_NDPROXY_SLAVE, 135 IFACE_ATTR_NDP_FROM_LINK_LOCAL, 136 IFACE_ATTR_PREFIX_FILTER, 137 IFACE_ATTR_MAX_PREFERRED_LIFETIME, 138 IFACE_ATTR_MAX_VALID_LIFETIME, 139 IFACE_ATTR_NTP, 140 IFACE_ATTR_CAPTIVE_PORTAL_URI, 141 IFACE_ATTR_IPV6_ONLY_PREFERRED, 142 IFACE_ATTR_DHCPV6_RELAY_SERVERS, 143 IFACE_ATTR_MAX 144 }; 145 146 static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { 147 [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING }, 148 [IFACE_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, 149 [IFACE_ATTR_NETWORKID] = { .name = "networkid", .type = BLOBMSG_TYPE_STRING }, 150 [IFACE_ATTR_DYNAMICDHCP] = { .name = "dynamicdhcp", .type = BLOBMSG_TYPE_BOOL }, 151 [IFACE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 152 [IFACE_ATTR_DHCPV4_POOL_START] = { .name = "start", .type = BLOBMSG_TYPE_INT32 }, 153 [IFACE_ATTR_DHCPV4_POOL_LIMIT] = { .name = "limit", .type = BLOBMSG_TYPE_INT32 }, 154 [IFACE_ATTR_MASTER] = { .name = "master", .type = BLOBMSG_TYPE_BOOL }, 155 [IFACE_ATTR_UPSTREAM] = { .name = "upstream", .type = BLOBMSG_TYPE_ARRAY }, 156 [IFACE_ATTR_RA] = { .name = "ra", .type = BLOBMSG_TYPE_STRING }, 157 [IFACE_ATTR_DHCPV4] = { .name = "dhcpv4", .type = BLOBMSG_TYPE_STRING }, 158 [IFACE_ATTR_DHCPV6] = { .name = "dhcpv6", .type = BLOBMSG_TYPE_STRING }, 159 [IFACE_ATTR_NDP] = { .name = "ndp", .type = BLOBMSG_TYPE_STRING }, 160 [IFACE_ATTR_ROUTER] = { .name = "router", .type = BLOBMSG_TYPE_ARRAY }, 161 [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY }, 162 [IFACE_ATTR_DNR] = { .name = "dnr", .type = BLOBMSG_TYPE_ARRAY }, 163 [IFACE_ATTR_DNS_SERVICE] = { .name = "dns_service", .type = BLOBMSG_TYPE_BOOL }, 164 [IFACE_ATTR_DNS_DOMAIN_SEARCH] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY }, 165 [IFACE_ATTR_DHCPV4_FORCERECONF] = { .name = "dhcpv4_forcereconf", .type = BLOBMSG_TYPE_BOOL }, 166 [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING }, 167 [IFACE_ATTR_DHCPV6_ASSIGNALL] = { .name ="dhcpv6_assignall", .type = BLOBMSG_TYPE_BOOL }, 168 [IFACE_ATTR_DHCPV6_PD_PREFERRED] = { .name = "dhcpv6_pd_preferred", .type = BLOBMSG_TYPE_BOOL }, 169 [IFACE_ATTR_DHCPV6_PD] = { .name = "dhcpv6_pd", .type = BLOBMSG_TYPE_BOOL }, 170 [IFACE_ATTR_DHCPV6_PD_MIN_LEN] = { .name = "dhcpv6_pd_min_len", .type = BLOBMSG_TYPE_INT32 }, 171 [IFACE_ATTR_DHCPV6_NA] = { .name = "dhcpv6_na", .type = BLOBMSG_TYPE_BOOL }, 172 [IFACE_ATTR_DHCPV6_HOSTID_LEN] = { .name = "dhcpv6_hostidlength", .type = BLOBMSG_TYPE_INT32 }, 173 [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 }, 174 [IFACE_ATTR_RA_FLAGS] = { .name = "ra_flags", . type = BLOBMSG_TYPE_ARRAY }, 175 [IFACE_ATTR_RA_SLAAC] = { .name = "ra_slaac", .type = BLOBMSG_TYPE_BOOL }, 176 [IFACE_ATTR_RA_OFFLINK] = { .name = "ra_offlink", .type = BLOBMSG_TYPE_BOOL }, 177 [IFACE_ATTR_RA_PREFERENCE] = { .name = "ra_preference", .type = BLOBMSG_TYPE_STRING }, 178 [IFACE_ATTR_RA_ADVROUTER] = { .name = "ra_advrouter", .type = BLOBMSG_TYPE_BOOL }, 179 [IFACE_ATTR_RA_MININTERVAL] = { .name = "ra_mininterval", .type = BLOBMSG_TYPE_INT32 }, 180 [IFACE_ATTR_RA_MAXINTERVAL] = { .name = "ra_maxinterval", .type = BLOBMSG_TYPE_INT32 }, 181 [IFACE_ATTR_RA_LIFETIME] = { .name = "ra_lifetime", .type = BLOBMSG_TYPE_INT32 }, 182 [IFACE_ATTR_RA_REACHABLETIME] = { .name = "ra_reachabletime", .type = BLOBMSG_TYPE_INT32 }, 183 [IFACE_ATTR_RA_RETRANSTIME] = { .name = "ra_retranstime", .type = BLOBMSG_TYPE_INT32 }, 184 [IFACE_ATTR_RA_HOPLIMIT] = { .name = "ra_hoplimit", .type = BLOBMSG_TYPE_INT32 }, 185 [IFACE_ATTR_RA_MTU] = { .name = "ra_mtu", .type = BLOBMSG_TYPE_INT32 }, 186 [IFACE_ATTR_RA_DNS] = { .name = "ra_dns", .type = BLOBMSG_TYPE_BOOL }, 187 [IFACE_ATTR_RA_PREF64] = { .name = "ra_pref64", .type = BLOBMSG_TYPE_STRING }, 188 [IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = BLOBMSG_TYPE_BOOL }, 189 [IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = BLOBMSG_TYPE_BOOL }, 190 [IFACE_ATTR_NDP_FROM_LINK_LOCAL] = { .name = "ndp_from_link_local", .type = BLOBMSG_TYPE_BOOL }, 191 [IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = BLOBMSG_TYPE_STRING }, 192 [IFACE_ATTR_MAX_PREFERRED_LIFETIME] = { .name = "max_preferred_lifetime", .type = BLOBMSG_TYPE_STRING }, 193 [IFACE_ATTR_MAX_VALID_LIFETIME] = { .name = "max_valid_lifetime", .type = BLOBMSG_TYPE_STRING }, 194 [IFACE_ATTR_NTP] = { .name = "ntp", .type = BLOBMSG_TYPE_ARRAY }, 195 [IFACE_ATTR_CAPTIVE_PORTAL_URI] = { .name = "captive_portal_uri", .type = BLOBMSG_TYPE_STRING }, 196 [IFACE_ATTR_IPV6_ONLY_PREFERRED] = { .name = "ipv6_only_preferred", .type = BLOBMSG_TYPE_INT32 }, 197 [IFACE_ATTR_DHCPV6_RELAY_SERVERS] = { .name = "dhcpv6_relay_servers", .type = BLOBMSG_TYPE_ARRAY }, 198 }; 199 200 const struct uci_blob_param_list interface_attr_list = { 201 .n_params = IFACE_ATTR_MAX, 202 .params = iface_attrs, 203 }; 204 205 const struct blobmsg_policy lease_cfg_attrs[LEASE_CFG_ATTR_MAX] = { 206 [LEASE_CFG_ATTR_IPV4] = { .name = "ip", .type = BLOBMSG_TYPE_STRING }, 207 [LEASE_CFG_ATTR_MAC] = { .name = "mac", .type = BLOBMSG_TYPE_ARRAY }, 208 [LEASE_CFG_ATTR_DUID] = { .name = "duid", .type = BLOBMSG_TYPE_ARRAY }, 209 [LEASE_CFG_ATTR_HOSTID] = { .name = "hostid", .type = BLOBMSG_TYPE_STRING }, 210 [LEASE_CFG_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 211 [LEASE_CFG_ATTR_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 212 }; 213 214 const struct uci_blob_param_list lease_cfg_attr_list = { 215 .n_params = LEASE_CFG_ATTR_MAX, 216 .params = lease_cfg_attrs, 217 }; 218 219 enum { 220 ODHCPD_ATTR_MAINDHCP, 221 ODHCPD_ATTR_LEASEFILE, 222 ODHCPD_ATTR_LEASETRIGGER, 223 ODHCPD_ATTR_LOGLEVEL, 224 ODHCPD_ATTR_HOSTSDIR, 225 ODHCPD_ATTR_PIODIR, 226 ODHCPD_ATTR_ENABLE_TZ, 227 ODHCPD_ATTR_MAX 228 }; 229 230 static const struct blobmsg_policy odhcpd_attrs[ODHCPD_ATTR_MAX] = { 231 [ODHCPD_ATTR_MAINDHCP] = { .name = "maindhcp", .type = BLOBMSG_TYPE_BOOL }, 232 [ODHCPD_ATTR_LEASEFILE] = { .name = "leasefile", .type = BLOBMSG_TYPE_STRING }, 233 [ODHCPD_ATTR_LEASETRIGGER] = { .name = "leasetrigger", .type = BLOBMSG_TYPE_STRING }, 234 [ODHCPD_ATTR_LOGLEVEL] = { .name = "loglevel", .type = BLOBMSG_TYPE_INT32 }, 235 [ODHCPD_ATTR_HOSTSDIR] = { .name = "hostsdir", .type = BLOBMSG_TYPE_STRING }, 236 [ODHCPD_ATTR_PIODIR] = { .name = "piodir", .type = BLOBMSG_TYPE_STRING }, 237 [ODHCPD_ATTR_ENABLE_TZ] = { .name = "enable_tz", .type = BLOBMSG_TYPE_BOOL }, 238 }; 239 240 const struct uci_blob_param_list odhcpd_attr_list = { 241 .n_params = ODHCPD_ATTR_MAX, 242 .params = odhcpd_attrs, 243 }; 244 245 enum { 246 SYSTEM_ATTR_TIMEZONE, 247 SYSTEM_ATTR_ZONENAME, 248 SYSTEM_ATTR_MAX 249 }; 250 251 static const struct blobmsg_policy system_attrs[SYSTEM_ATTR_MAX] = { 252 [SYSTEM_ATTR_TIMEZONE] = { .name = "timezone", .type = BLOBMSG_TYPE_STRING }, 253 [SYSTEM_ATTR_ZONENAME] = { .name = "zonename", .type = BLOBMSG_TYPE_STRING }, 254 }; 255 256 const struct uci_blob_param_list system_attr_list = { 257 .n_params = SYSTEM_ATTR_MAX, 258 .params = system_attrs, 259 }; 260 261 enum { 262 GLOBAL_ATTR_DUID, 263 GLOBAL_ATTR_MAX 264 }; 265 266 static const struct blobmsg_policy global_attrs[GLOBAL_ATTR_MAX] = { 267 [GLOBAL_ATTR_DUID] = { .name = "dhcp_default_duid", .type = BLOBMSG_TYPE_STRING }, 268 }; 269 270 const struct uci_blob_param_list global_attr_list = { 271 .n_params = GLOBAL_ATTR_MAX, 272 .params = global_attrs, 273 }; 274 275 static const struct { const char *name; uint8_t flag; } ra_flags[] = { 276 { .name = "managed-config", .flag = ND_RA_FLAG_MANAGED }, 277 { .name = "other-config", .flag = ND_RA_FLAG_OTHER }, 278 { .name = "home-agent", .flag = ND_RA_FLAG_HOME_AGENT }, 279 { .name = "none", . flag = 0 }, 280 { .name = NULL, }, 281 }; 282 283 // https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml 284 enum svc_param_keys { 285 DNR_SVC_MANDATORY, 286 DNR_SVC_ALPN, 287 DNR_SVC_NO_DEFAULT_ALPN, 288 DNR_SVC_PORT, 289 DNR_SVC_IPV4HINT, 290 DNR_SVC_ECH, 291 DNR_SVC_IPV6HINT, 292 DNR_SVC_DOHPATH, 293 DNR_SVC_OHTTP, 294 DNR_SVC_MAX, 295 }; 296 297 static const char *svc_param_key_names[DNR_SVC_MAX] = { 298 [DNR_SVC_MANDATORY] = "mandatory", 299 [DNR_SVC_ALPN] = "alpn", 300 [DNR_SVC_NO_DEFAULT_ALPN] = "no-default-alpn", 301 [DNR_SVC_PORT] = "port", 302 [DNR_SVC_IPV4HINT] = "ipv4hint", 303 [DNR_SVC_ECH] = "ech", 304 [DNR_SVC_IPV6HINT] = "ipv6hint", 305 [DNR_SVC_DOHPATH] = "dohpath", 306 [DNR_SVC_OHTTP] = "ohttp", 307 }; 308 309 static void set_interface_defaults(struct interface *iface) 310 { 311 iface->ignore = true; 312 iface->dhcpv4 = MODE_DISABLED; 313 iface->dhcpv6 = MODE_DISABLED; 314 iface->ra = MODE_DISABLED; 315 iface->ndp = MODE_DISABLED; 316 iface->learn_routes = 1; 317 iface->ndp_from_link_local = true; 318 iface->cached_linklocal_valid = false; 319 iface->dhcp_leasetime = 43200; 320 iface->max_preferred_lifetime = ND_PREFERRED_LIMIT; 321 iface->max_valid_lifetime = ND_VALID_LIMIT; 322 iface->captive_portal_uri = NULL; 323 iface->dhcpv4_pool_start = 0; 324 iface->dhcpv4_pool_end = 0; 325 iface->dhcpv6_assignall = true; 326 iface->dhcpv6_pd = true; 327 iface->dhcpv6_pd_preferred = false; 328 iface->dhcpv6_pd_min_len = PD_MIN_LEN_DEFAULT; 329 iface->dhcpv6_na = true; 330 iface->dhcpv6_hostid_len = HOSTID_LEN_DEFAULT; 331 iface->dns_service = true; 332 iface->ra_flags = ND_RA_FLAG_OTHER; 333 iface->ra_slaac = true; 334 iface->ra_maxinterval = 600; 335 /* 336 * RFC4861: MinRtrAdvInterval: Default: 0.33 * MaxRtrAdvInterval If 337 * MaxRtrAdvInterval >= 9 seconds; otherwise, the Default is MaxRtrAdvInterval. 338 */ 339 iface->ra_mininterval = iface->ra_maxinterval/3; 340 iface->ra_lifetime = 3 * iface->ra_maxinterval; /* RFC4861: AdvDefaultLifetime: Default: 3 * MaxRtrAdvInterval */ 341 iface->ra_dns = true; 342 iface->pio_update = false; 343 iface->update_statefile = true; 344 } 345 346 static void clean_interface(struct interface *iface) 347 { 348 free(iface->dns_addrs4); 349 free(iface->dns_addrs6); 350 free(iface->dns_search); 351 free(iface->upstream); 352 free(iface->dhcpv4_routers); 353 free(iface->dhcpv6_raw); 354 free(iface->dhcpv4_ntp); 355 free(iface->dhcpv6_ntp); 356 free(iface->dhcpv6_relay_server_addrs6); 357 free(iface->dhcpv6_sntp); 358 free(iface->captive_portal_uri); 359 for (unsigned i = 0; i < iface->dnr_cnt; i++) { 360 free(iface->dnr[i].adn); 361 free(iface->dnr[i].addr4); 362 free(iface->dnr[i].addr6); 363 free(iface->dnr[i].svc); 364 } 365 free(iface->dnr); 366 free(iface->pios); 367 memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra)); 368 set_interface_defaults(iface); 369 } 370 371 static void close_interface(struct interface *iface) 372 { 373 avl_delete(&interfaces, &iface->avl); 374 375 router_setup_interface(iface, false); 376 dhcpv6_setup_interface(iface, false); 377 ndp_setup_interface(iface, false); 378 dhcpv4_setup_interface(iface, false); 379 380 /* make sure timer is not on the timeouts list before freeing */ 381 uloop_timeout_cancel(&iface->timer_rs); 382 383 clean_interface(iface); 384 free(iface->oaddrs4); 385 free(iface->addr6); 386 free(iface->ifname); 387 free(iface); 388 } 389 390 static int parse_mode(const char *mode) 391 { 392 if (!strcmp(mode, "disabled")) 393 return MODE_DISABLED; 394 else if (!strcmp(mode, "server")) 395 return MODE_SERVER; 396 else if (!strcmp(mode, "relay")) 397 return MODE_RELAY; 398 else if (!strcmp(mode, "hybrid")) 399 return MODE_HYBRID; 400 else 401 return -1; 402 } 403 404 static int parse_ra_flags(uint8_t *flags, struct blob_attr *attr) 405 { 406 struct blob_attr *cur; 407 unsigned rem; 408 409 blobmsg_for_each_attr(cur, attr, rem) { 410 int i; 411 412 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 413 continue; 414 415 if (!blobmsg_check_attr(cur, false)) 416 continue; 417 418 for (i = 0; ra_flags[i].name; i++) { 419 if (!strcmp(ra_flags[i].name, blobmsg_get_string(cur))) { 420 *flags |= ra_flags[i].flag; 421 break; 422 } 423 } 424 425 if (!ra_flags[i].name) 426 return -1; 427 } 428 429 return 0; 430 } 431 432 static void set_global_config(struct uci_section *s) 433 { 434 struct blob_attr *tb[GLOBAL_ATTR_MAX], *c; 435 436 blob_buf_init(&b, 0); 437 uci_to_blob(&b, s, &global_attr_list); 438 blobmsg_parse(global_attrs, GLOBAL_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head)); 439 440 if ((c = tb[GLOBAL_ATTR_DUID])) { 441 size_t len = blobmsg_data_len(c) / 2; 442 443 config.default_duid_len = 0; 444 if (len >= DUID_MIN_LEN && len <= DUID_MAX_LEN) { 445 ssize_t r = odhcpd_unhexlify(config.default_duid, len, blobmsg_get_string(c)); 446 if (r >= DUID_MIN_LEN) 447 config.default_duid_len = r; 448 } 449 } 450 } 451 452 static void set_config(struct uci_section *s) 453 { 454 struct blob_attr *tb[ODHCPD_ATTR_MAX], *c; 455 456 blob_buf_init(&b, 0); 457 uci_to_blob(&b, s, &odhcpd_attr_list); 458 blobmsg_parse(odhcpd_attrs, ODHCPD_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head)); 459 460 if ((c = tb[ODHCPD_ATTR_MAINDHCP])) 461 config.main_dhcpv4 = blobmsg_get_bool(c); 462 463 if ((c = tb[ODHCPD_ATTR_LEASEFILE])) { 464 free(config.dhcp_statefile); 465 config.dhcp_statefile = strdup(blobmsg_get_string(c)); 466 } 467 468 if ((c = tb[ODHCPD_ATTR_HOSTSDIR])) { 469 free(config.dhcp_hostsdir); 470 config.dhcp_hostsdir = strdup(blobmsg_get_string(c)); 471 } 472 473 if ((c = tb[ODHCPD_ATTR_PIODIR])) { 474 free(config.ra_piodir); 475 config.ra_piodir = strdup(blobmsg_get_string(c)); 476 } 477 478 if ((c = tb[ODHCPD_ATTR_LEASETRIGGER])) { 479 free(config.dhcp_cb); 480 config.dhcp_cb = strdup(blobmsg_get_string(c)); 481 } 482 483 if ((c = tb[ODHCPD_ATTR_LOGLEVEL])) { 484 int log_level = (blobmsg_get_u32(c) & LOG_PRIMASK); 485 486 if (config.log_level != log_level && !config.log_level_cmdline) { 487 config.log_level = log_level; 488 if (config.log_syslog) 489 setlogmask(LOG_UPTO(config.log_level)); 490 notice("Log level set to %d\n", config.log_level); 491 } 492 } 493 494 if ((c = tb[ODHCPD_ATTR_ENABLE_TZ])) 495 config.enable_tz = blobmsg_get_bool(c); 496 497 if (config.dhcp_statefile) { 498 char *dir = dirname(strdupa(config.dhcp_statefile)); 499 char *file = basename(config.dhcp_statefile); 500 501 memmove(config.dhcp_statefile, file, strlen(file) + 1); 502 statefiles_setup_dirfd(dir, &config.dhcp_statedir_fd); 503 } else { 504 statefiles_setup_dirfd(NULL, &config.dhcp_statedir_fd); 505 } 506 statefiles_setup_dirfd(config.dhcp_hostsdir, &config.dhcp_hostsdir_fd); 507 statefiles_setup_dirfd(config.ra_piodir, &config.ra_piodir_fd); 508 } 509 510 static void sanitize_tz_string(const char *src, uint8_t **dst, size_t *dst_len) 511 { 512 /* replace any spaces with '_' in tz strings. luci, where these strings 513 are normally set, (had a bug that) replaced underscores for spaces in the 514 names. */ 515 516 if (!dst || !dst_len) 517 return; 518 519 free(*dst); 520 *dst = NULL; 521 *dst_len = 0; 522 523 if (!src || !*src) 524 return; 525 526 char *copy = strdup(src); 527 if (!copy) 528 return; 529 530 for (char *p = copy; *p; p++) { 531 if (isspace((unsigned char)*p)) 532 *p = '_'; 533 } 534 535 *dst = (uint8_t *)copy; 536 *dst_len = strlen(copy); 537 } 538 539 static void set_timezone_info_from_uci(struct uci_section *s) 540 { 541 struct blob_attr *tb[SYSTEM_ATTR_MAX], *c; 542 543 blob_buf_init(&b, 0); 544 uci_to_blob(&b, s, &system_attr_list); 545 blobmsg_parse(system_attrs, SYSTEM_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head)); 546 547 if ((c = tb[SYSTEM_ATTR_TIMEZONE])) 548 sanitize_tz_string(blobmsg_get_string(c), &sys_conf.posix_tz, &sys_conf.posix_tz_len); 549 550 if ((c = tb[SYSTEM_ATTR_ZONENAME])) 551 sanitize_tz_string(blobmsg_get_string(c), &sys_conf.tzdb_tz, &sys_conf.tzdb_tz_len); 552 } 553 554 static uint32_t parse_leasetime(struct blob_attr *c) { 555 char *val = blobmsg_get_string(c), *endptr = NULL; 556 uint32_t time = strcmp(val, "infinite") ? (uint32_t)strtod(val, &endptr) : UINT32_MAX; 557 558 if (time && endptr && endptr[0]) { 559 switch(endptr[0]) { 560 case 's': break; /* seconds */ 561 case 'm': time *= 60; break; /* minutes */ 562 case 'h': time *= 3600; break; /* hours */ 563 case 'd': time *= 24 * 3600; break; /* days */ 564 case 'w': time *= 7 * 24 * 3600; break; /* weeks */ 565 default: goto err; 566 } 567 } 568 569 if (time < 60) 570 time = 60; 571 572 return time; 573 574 err: 575 return 0; 576 } 577 578 static void free_lease_cfg(struct lease_cfg *lease_cfg) 579 { 580 if (!lease_cfg) 581 return; 582 583 free(lease_cfg->hostname); 584 free(lease_cfg); 585 } 586 587 static bool parse_duid(struct duid *duid, struct blob_attr *c) 588 { 589 const char *duid_str = blobmsg_get_string(c); 590 size_t duid_str_len = blobmsg_data_len(c) - 1; 591 ssize_t duid_len; 592 const char *iaid_str; 593 594 /* We support a hex string with either "<DUID>", or "<DUID>%<IAID>" */ 595 iaid_str = strrchr(duid_str, '%'); 596 if (iaid_str) { 597 size_t iaid_str_len = strlen(++iaid_str); 598 char *end; 599 600 /* IAID = uint32, RFC8415, §21.4, §21.5, §21.21 */ 601 if (iaid_str_len < 1 || iaid_str_len > 2 * sizeof(uint32_t)) { 602 error("Invalid IAID length '%s'", iaid_str); 603 return false; 604 } 605 606 errno = 0; 607 duid->iaid = strtoul(iaid_str, &end, 16); 608 if (errno || *end != '\0') { 609 error("Invalid IAID '%s'", iaid_str); 610 return false; 611 } 612 613 duid->iaid_set = true; 614 duid_str_len -= (iaid_str_len + 1); 615 } 616 617 if (duid_str_len < 2 || duid_str_len > DUID_MAX_LEN * 2 || duid_str_len % 2) { 618 error("Invalid DUID length '%.*s'", (int)duid_str_len, duid_str); 619 return false; 620 } 621 622 duid_len = odhcpd_unhexlify(duid->id, duid_str_len / 2, duid_str); 623 if (duid_len < 0) { 624 error("Invalid DUID '%.*s'", (int)duid_str_len, duid_str); 625 return false; 626 } 627 628 duid->len = duid_len; 629 return true; 630 } 631 632 int config_set_lease_cfg_from_blobmsg(struct blob_attr *ba) 633 { 634 struct blob_attr *tb[LEASE_CFG_ATTR_MAX], *c; 635 struct lease_cfg *lease_cfg = NULL; 636 int mac_count = 0; 637 struct ether_addr *macs; 638 int duid_count = 0; 639 struct duid *duids; 640 641 blobmsg_parse(lease_cfg_attrs, LEASE_CFG_ATTR_MAX, tb, blob_data(ba), blob_len(ba)); 642 643 if ((c = tb[LEASE_CFG_ATTR_MAC])) { 644 mac_count = blobmsg_check_array_len(c, BLOBMSG_TYPE_STRING, blob_raw_len(c)); 645 if (mac_count < 0) 646 goto err; 647 } 648 649 if ((c = tb[LEASE_CFG_ATTR_DUID])) { 650 duid_count = blobmsg_check_array_len(c, BLOBMSG_TYPE_STRING, blob_raw_len(c)); 651 if (duid_count < 0) 652 goto err; 653 } 654 655 lease_cfg = calloc_a(sizeof(*lease_cfg), 656 &macs, mac_count * sizeof(*macs), 657 &duids, duid_count * sizeof(*duids)); 658 if (!lease_cfg) 659 goto err; 660 661 if ((c = tb[LEASE_CFG_ATTR_MAC])) { 662 struct blob_attr *cur; 663 size_t rem; 664 int i = 0; 665 666 lease_cfg->mac_count = mac_count; 667 lease_cfg->macs = macs; 668 669 blobmsg_for_each_attr(cur, c, rem) 670 if (!ether_aton_r(blobmsg_get_string(cur), &lease_cfg->macs[i++])) 671 goto err; 672 } 673 674 if ((c = tb[LEASE_CFG_ATTR_DUID])) { 675 struct blob_attr *cur; 676 size_t rem; 677 unsigned i = 0; 678 679 lease_cfg->duid_count = duid_count; 680 lease_cfg->duids = duids; 681 682 blobmsg_for_each_attr(cur, c, rem) 683 if (!parse_duid(&duids[i++], cur)) 684 goto err; 685 } 686 687 if ((c = tb[LEASE_CFG_ATTR_NAME])) { 688 if (!odhcpd_hostname_valid(blobmsg_get_string(c))) 689 goto err; 690 691 lease_cfg->hostname = strdup(blobmsg_get_string(c)); 692 if (!lease_cfg->hostname) 693 goto err; 694 } 695 696 if ((c = tb[LEASE_CFG_ATTR_IPV4])) { 697 const char *ip = blobmsg_get_string(c); 698 699 if (!strcmp(ip, "ignore")) 700 lease_cfg->ignore4 = true; 701 else if (inet_pton(AF_INET, blobmsg_get_string(c), &lease_cfg->ipv4) != 1) 702 goto err; 703 } 704 705 if ((c = tb[LEASE_CFG_ATTR_HOSTID])) { 706 const char *iid = blobmsg_get_string(c); 707 708 if (!strcmp(iid, "ignore")) { 709 lease_cfg->ignore6 = true; 710 } else { 711 errno = 0; 712 lease_cfg->hostid = strtoull(blobmsg_get_string(c), NULL, 16); 713 if (errno) 714 goto err; 715 } 716 } else { 717 uint32_t i4a = ntohl(lease_cfg->ipv4.s_addr) & 0xff; 718 lease_cfg->hostid = ((i4a / 100) << 8) | (((i4a % 100) / 10) << 4) | (i4a % 10); 719 } 720 721 if ((c = tb[LEASE_CFG_ATTR_LEASETIME])) { 722 uint32_t time = parse_leasetime(c); 723 if (time == 0) 724 goto err; 725 726 lease_cfg->leasetime = time; 727 } 728 729 INIT_LIST_HEAD(&lease_cfg->dhcpv6_leases); 730 vlist_add(&lease_cfgs, &lease_cfg->node, lease_cfg); 731 return 0; 732 733 err: 734 free_lease_cfg(lease_cfg); 735 return -1; 736 } 737 738 static int set_lease_cfg_from_uci(struct uci_section *s) 739 { 740 blob_buf_init(&b, 0); 741 uci_to_blob(&b, s, &lease_cfg_attr_list); 742 743 return config_set_lease_cfg_from_blobmsg(b.head); 744 } 745 746 /* Parse NTP Options for DHCPv6 Address */ 747 static int parse_ntp_options(uint16_t *dhcpv6_ntp_len, struct in6_addr addr6, uint8_t **dhcpv6_ntp) 748 { 749 uint16_t sub_opt = 0, sub_len = htons(IPV6_ADDR_LEN); 750 uint16_t ntp_len = IPV6_ADDR_LEN + 4; 751 uint8_t *ntp; 752 size_t pos = *dhcpv6_ntp_len; 753 754 ntp = realloc(*dhcpv6_ntp, pos + ntp_len); 755 if (!ntp) 756 return -1; 757 758 *dhcpv6_ntp = ntp; 759 760 if (IN6_IS_ADDR_MULTICAST(&addr6)) 761 sub_opt = htons(NTP_SUBOPTION_MC_ADDR); 762 else 763 sub_opt = htons(NTP_SUBOPTION_SRV_ADDR); 764 765 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 766 pos += sizeof(sub_opt); 767 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 768 pos += sizeof(sub_len); 769 memcpy(ntp + pos, &addr6, IPV6_ADDR_LEN); 770 771 *dhcpv6_ntp_len += ntp_len; 772 773 return 0; 774 } 775 776 /* Parse NTP Options for FQDN */ 777 static int parse_ntp_fqdn(uint16_t *dhcpv6_ntp_len, char *fqdn, uint8_t **dhcpv6_ntp) 778 { 779 size_t fqdn_len = strlen(fqdn); 780 uint16_t sub_opt = 0, sub_len = 0, ntp_len = 0; 781 uint8_t *ntp; 782 size_t pos = *dhcpv6_ntp_len; 783 uint8_t buf[256] = {0}; 784 785 if (fqdn_len > 0 && fqdn[fqdn_len - 1] == '.') 786 fqdn[fqdn_len - 1] = 0; 787 788 int len = dn_comp(fqdn, buf, sizeof(buf), NULL, NULL); 789 if (len <= 0) 790 return -1; 791 792 ntp_len = len + 4; 793 794 ntp = realloc(*dhcpv6_ntp, pos + ntp_len); 795 if (!ntp) 796 return -1; 797 798 *dhcpv6_ntp = ntp; 799 800 sub_opt = htons(NTP_SUBOPTION_SRV_FQDN); 801 sub_len = htons(len); 802 803 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 804 pos += sizeof(sub_opt); 805 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 806 pos += sizeof(sub_len); 807 memcpy(ntp + pos, buf, len); 808 809 *dhcpv6_ntp_len += ntp_len; 810 811 return 0; 812 } 813 814 /* Parse DNR Options */ 815 static int parse_dnr_str(char *str, struct interface *iface) 816 { 817 struct dnr_options dnr = {0}; 818 size_t adn_len; 819 uint8_t adn_buf[256] = {0}; 820 char *saveptr1, *saveptr2; 821 822 char *priority; 823 priority = strtok_r(str, " \f\n\r\t\v", &saveptr1); 824 if (!priority) { 825 goto err; 826 } else if (sscanf(priority, "%" SCNu16, &dnr.priority) != 1) { 827 error("Unable to parse priority '%s'", priority); 828 goto err; 829 } else if (dnr.priority == 0) { 830 error("Invalid priority '%s'", priority); 831 goto err; 832 } 833 834 char *adn; 835 adn = strtok_r(NULL, " \f\n\r\t\v", &saveptr1); 836 if (!adn) 837 goto err; 838 839 adn_len = strlen(adn); 840 if (adn_len > 0 && adn[adn_len - 1] == '.') 841 adn[adn_len - 1] = '\0'; 842 843 if (adn_len >= sizeof(adn_buf)) { 844 error("Hostname '%s' too long", adn); 845 goto err; 846 } 847 848 adn_len = dn_comp(adn, adn_buf, sizeof(adn_buf), NULL, NULL); 849 if (adn_len <= 0) { 850 error("Unable to parse hostname '%s'", adn); 851 goto err; 852 } 853 854 dnr.adn = malloc(adn_len); 855 if (!dnr.adn) 856 goto err; 857 memcpy(dnr.adn, adn_buf, adn_len); 858 dnr.adn_len = adn_len; 859 860 char *addrs; 861 addrs = strtok_r(NULL, " \f\n\r\t\v", &saveptr1); 862 if (!addrs) 863 // ADN-Only mode 864 goto done; 865 866 for (char *addr = strtok_r(addrs, ",", &saveptr2); addr; addr = strtok_r(NULL, ",", &saveptr2)) { 867 struct in6_addr addr6, *tmp6; 868 struct in_addr addr4, *tmp4; 869 size_t new_sz; 870 871 if (inet_pton(AF_INET6, addr, &addr6) == 1) { 872 new_sz = (dnr.addr6_cnt + 1) * sizeof(*dnr.addr6); 873 if (new_sz > UINT16_MAX) 874 continue; 875 tmp6 = realloc(dnr.addr6, new_sz); 876 if (!tmp6) 877 goto err; 878 dnr.addr6 = tmp6; 879 memcpy(&dnr.addr6[dnr.addr6_cnt], &addr6, sizeof(*dnr.addr6)); 880 dnr.addr6_cnt++; 881 882 } else if (inet_pton(AF_INET, addr, &addr4) == 1) { 883 new_sz = (dnr.addr4_cnt + 1) * sizeof(*dnr.addr4); 884 if (new_sz > UINT8_MAX) 885 continue; 886 tmp4 = realloc(dnr.addr4, new_sz); 887 if (!tmp4) 888 goto err; 889 dnr.addr4 = tmp4; 890 memcpy(&dnr.addr4[dnr.addr4_cnt], &addr4, sizeof(*dnr.addr4)); 891 dnr.addr4_cnt++; 892 893 } else { 894 error("Unable to parse IP address '%s'", addr); 895 goto err; 896 } 897 } 898 899 char *svc_vals[DNR_SVC_MAX] = { NULL, }; 900 for (char *svc_tok = strtok_r(NULL, " \f\n\r\t\v", &saveptr1); svc_tok; svc_tok = strtok_r(NULL, " \f\n\r\t\v", &saveptr1)) { 901 uint16_t svc_id; 902 char *svc_key, *svc_val; 903 904 svc_key = strtok_r(svc_tok, "=", &saveptr2); 905 svc_val = strtok_r(NULL, "=", &saveptr2); 906 907 if (!strcmp(svc_key, "_lifetime")) { 908 uint32_t lifetime; 909 910 if (!svc_val || sscanf(svc_val, "%" SCNu32, &lifetime) != 1) { 911 error("Invalid value '%s' for _lifetime", svc_val ? svc_val : ""); 912 goto err; 913 } 914 915 dnr.lifetime = lifetime; 916 dnr.lifetime_set = true; 917 continue; 918 } 919 920 for (svc_id = 0; svc_id < DNR_SVC_MAX; svc_id++) 921 if (!strcmp(svc_key, svc_param_key_names[svc_id])) 922 break; 923 924 if (svc_id >= DNR_SVC_MAX) { 925 error("Invalid SvcParam '%s'", svc_key); 926 goto err; 927 } 928 929 svc_vals[svc_id] = svc_val ? svc_val : ""; 930 } 931 932 /* SvcParamKeys must be in increasing order, RFC9460 §2.2 */ 933 for (uint16_t svc_key = 0; svc_key < DNR_SVC_MAX; svc_key++) { 934 uint16_t svc_key_be = ntohs(svc_key); 935 uint16_t svc_val_len, svc_val_len_be; 936 char *svc_val_str = svc_vals[svc_key]; 937 uint8_t *tmp; 938 939 if (!svc_val_str) 940 continue; 941 942 switch (svc_key) { 943 case DNR_SVC_MANDATORY: 944 uint16_t mkeys[DNR_SVC_MAX]; 945 946 svc_val_len = 0; 947 for (char *mkey_str = strtok_r(svc_val_str, ",", &saveptr2); mkey_str; mkey_str = strtok_r(NULL, ",", &saveptr2)) { 948 uint16_t mkey; 949 950 for (mkey = 0; mkey < DNR_SVC_MAX; mkey++) 951 if (!strcmp(mkey_str, svc_param_key_names[mkey])) 952 break; 953 954 if (mkey >= DNR_SVC_MAX || !svc_vals[mkey]) { 955 error("Invalid value '%s' for SvcParam 'mandatory'", mkey_str); 956 goto err; 957 } 958 959 if (svc_val_len >= DNR_SVC_MAX) { 960 error("Too many keys for SvcParam 'mandatory'"); 961 goto err; 962 } 963 964 mkeys[svc_val_len++] = ntohs(mkey); 965 } 966 967 svc_val_len *= sizeof(uint16_t); 968 svc_val_len_be = ntohs(svc_val_len); 969 970 tmp = realloc(dnr.svc, dnr.svc_len + 4 + svc_val_len); 971 if (!tmp) 972 goto err; 973 974 dnr.svc = tmp; 975 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 976 memcpy(dnr.svc + dnr.svc_len + 2, &svc_val_len_be, sizeof(svc_val_len_be)); 977 memcpy(dnr.svc + dnr.svc_len + 4, mkeys, svc_val_len); 978 dnr.svc_len += 4 + svc_val_len; 979 break; 980 981 case DNR_SVC_ALPN: 982 size_t len_off; 983 984 tmp = realloc(dnr.svc, dnr.svc_len + 4); 985 if (!tmp) 986 goto err; 987 988 dnr.svc = tmp; 989 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 990 /* the length is not known yet */ 991 len_off = dnr.svc_len + sizeof(svc_key_be); 992 dnr.svc_len += 4; 993 994 svc_val_len = 0; 995 for (char *alpn_id_str = strtok_r(svc_val_str, ",", &saveptr2); alpn_id_str; alpn_id_str = strtok_r(NULL, ",", &saveptr2)) { 996 size_t alpn_id_len; 997 998 alpn_id_len = strlen(alpn_id_str); 999 if (alpn_id_len > UINT8_MAX) { 1000 error("Invalid value '%s' for SvcParam 'alpn'", alpn_id_str); 1001 goto err; 1002 } 1003 1004 tmp = realloc(dnr.svc, dnr.svc_len + 1 + alpn_id_len); 1005 if (!tmp) 1006 goto err; 1007 dnr.svc = tmp; 1008 1009 dnr.svc[dnr.svc_len] = alpn_id_len; 1010 memcpy(dnr.svc + dnr.svc_len + 1, alpn_id_str, alpn_id_len); 1011 dnr.svc_len += 1 + alpn_id_len; 1012 svc_val_len += 1 + alpn_id_len; 1013 } 1014 1015 svc_val_len_be = ntohs(svc_val_len); 1016 memcpy(dnr.svc + len_off, &svc_val_len_be, sizeof(svc_val_len_be)); 1017 break; 1018 1019 case DNR_SVC_PORT: 1020 uint16_t port; 1021 1022 if (sscanf(svc_val_str, "%" SCNu16, &port) != 1) { 1023 error("Invalid value '%s' for SvcParam 'port'", svc_val_str); 1024 goto err; 1025 } 1026 1027 port = ntohs(port); 1028 svc_val_len_be = ntohs(2); 1029 1030 tmp = realloc(dnr.svc, dnr.svc_len + 6); 1031 if (!tmp) 1032 goto err; 1033 1034 dnr.svc = tmp; 1035 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 1036 memcpy(dnr.svc + dnr.svc_len + 2, &svc_val_len_be, sizeof(svc_val_len_be)); 1037 memcpy(dnr.svc + dnr.svc_len + 4, &port, sizeof(port)); 1038 dnr.svc_len += 6; 1039 break; 1040 1041 case DNR_SVC_NO_DEFAULT_ALPN: 1042 case DNR_SVC_OHTTP: 1043 if (strlen(svc_val_str) > 0) { 1044 error("Invalid value '%s' for SvcParam 'port'", svc_val_str); 1045 goto err; 1046 } 1047 _o_fallthrough; 1048 1049 case DNR_SVC_DOHPATH: 1050 /* plain string */ 1051 svc_val_len = strlen(svc_val_str); 1052 svc_val_len_be = ntohs(svc_val_len); 1053 tmp = realloc(dnr.svc, dnr.svc_len + 4 + svc_val_len); 1054 if (!tmp) 1055 goto err; 1056 1057 dnr.svc = tmp; 1058 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 1059 dnr.svc_len += sizeof(svc_key_be); 1060 memcpy(dnr.svc + dnr.svc_len, &svc_val_len_be, sizeof(svc_val_len_be)); 1061 dnr.svc_len += sizeof(svc_val_len_be); 1062 memcpy(dnr.svc + dnr.svc_len, svc_val_str, svc_val_len); 1063 dnr.svc_len += svc_val_len; 1064 break; 1065 1066 case DNR_SVC_ECH: 1067 error("SvcParam 'ech' is not implemented"); 1068 goto err; 1069 1070 case DNR_SVC_IPV4HINT: 1071 case DNR_SVC_IPV6HINT: 1072 error("SvcParam '%s' is not allowed", svc_param_key_names[svc_key]); 1073 goto err; 1074 } 1075 } 1076 1077 done: 1078 struct dnr_options *tmp; 1079 tmp = realloc(iface->dnr, (iface->dnr_cnt + 1) * sizeof(dnr)); 1080 if (!tmp) 1081 goto err; 1082 1083 iface->dnr = tmp; 1084 memcpy(iface->dnr + iface->dnr_cnt, &dnr, sizeof(dnr)); 1085 iface->dnr_cnt++; 1086 return 0; 1087 1088 err: 1089 free(dnr.adn); 1090 free(dnr.addr4); 1091 free(dnr.addr6); 1092 free(dnr.svc); 1093 return -1; 1094 } 1095 1096 static int avl_ipv4_cmp(const void *k1, const void *k2, _o_unused void *ptr) 1097 { 1098 return memcmp(k1, k2, sizeof(struct in_addr)); 1099 } 1100 1101 int config_parse_interface(void *data, size_t len, const char *name, bool overwrite) 1102 { 1103 struct interface *iface; 1104 struct blob_attr *tb[IFACE_ATTR_MAX], *c; 1105 struct odhcpd_ipaddr *oaddrs = NULL; 1106 ssize_t oaddrs_cnt; 1107 bool get_addrs = false; 1108 int mode; 1109 const char *ifname = NULL; 1110 1111 blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, data, len); 1112 1113 if (tb[IFACE_ATTR_INTERFACE]) 1114 name = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]); 1115 1116 if (!name) 1117 return -1; 1118 1119 iface = avl_find_element(&interfaces, name, iface, avl); 1120 if (!iface) { 1121 char *new_name; 1122 1123 iface = calloc_a(sizeof(*iface), &new_name, strlen(name) + 1); 1124 if (!iface) 1125 return -1; 1126 1127 iface->name = strcpy(new_name, name); 1128 iface->avl.key = iface->name; 1129 iface->router_event.uloop.fd = -1; 1130 iface->dhcpv6_event.uloop.fd = -1; 1131 iface->ndp_event.uloop.fd = -1; 1132 iface->ndp_ping_fd = -1; 1133 iface->dhcpv4_event.uloop.fd = -1; 1134 INIT_LIST_HEAD(&iface->ia_assignments); 1135 avl_init(&iface->dhcpv4_leases, avl_ipv4_cmp, false, iface); 1136 INIT_LIST_HEAD(&iface->dhcpv4_fr_ips); 1137 1138 set_interface_defaults(iface); 1139 1140 avl_insert(&interfaces, &iface->avl); 1141 get_addrs = overwrite = true; 1142 } 1143 1144 if (overwrite) { 1145 if ((c = tb[IFACE_ATTR_IFNAME])) 1146 ifname = blobmsg_get_string(c); 1147 else if ((c = tb[IFACE_ATTR_NETWORKID])) 1148 ifname = blobmsg_get_string(c); 1149 } 1150 1151 if (overwrite || !iface->ifname) 1152 if (config.use_ubus) 1153 ifname = ubus_get_ifname(name); 1154 1155 if (!iface->ifname && !ifname) 1156 goto err; 1157 1158 if (ifname) { 1159 free(iface->ifname); 1160 iface->ifname = strdup(ifname); 1161 1162 if (!iface->ifname) 1163 goto err; 1164 1165 if (!iface->ifindex && 1166 (iface->ifindex = if_nametoindex(iface->ifname)) <= 0) 1167 goto err; 1168 1169 if ((iface->ifflags = odhcpd_get_flags(iface)) < 0) 1170 goto err; 1171 } 1172 1173 if (get_addrs) { 1174 oaddrs_cnt = netlink_get_interface_addrs(iface->ifindex, 1175 true, &iface->addr6); 1176 1177 if (oaddrs_cnt > 0) 1178 iface->addr6_len = oaddrs_cnt; 1179 1180 oaddrs_cnt = netlink_get_interface_addrs(iface->ifindex, 1181 false, &iface->oaddrs4); 1182 if (oaddrs_cnt > 0) 1183 iface->oaddrs4_cnt = oaddrs_cnt; 1184 } 1185 1186 oaddrs_cnt = netlink_get_interface_linklocal(iface->ifindex, &oaddrs); 1187 if (oaddrs_cnt > 0) { 1188 for (ssize_t i = 0; i < oaddrs_cnt; i++) { 1189 if (!oaddrs[i].tentative) { 1190 iface->have_link_local = true; 1191 break; 1192 } 1193 } 1194 free(oaddrs); 1195 } 1196 1197 iface->inuse = true; 1198 1199 if ((c = tb[IFACE_ATTR_DYNAMICDHCP])) 1200 iface->no_dynamic_dhcp = !blobmsg_get_bool(c); 1201 1202 if ((c = tb[IFACE_ATTR_LEASETIME])) { 1203 uint32_t time = parse_leasetime(c); 1204 1205 if (time > 0) 1206 iface->dhcp_leasetime = time; 1207 else 1208 error("Invalid %s value configured for interface '%s'", 1209 iface_attrs[IFACE_ATTR_LEASETIME].name, iface->name); 1210 } 1211 1212 if ((c = tb[IFACE_ATTR_MAX_PREFERRED_LIFETIME])) { 1213 uint32_t time = parse_leasetime(c); 1214 1215 if (time > 0) 1216 iface->max_preferred_lifetime = time; 1217 else 1218 error("Invalid %s value configured for interface '%s'", 1219 iface_attrs[IFACE_ATTR_MAX_PREFERRED_LIFETIME].name, iface->name); 1220 } 1221 1222 if ((c = tb[IFACE_ATTR_MAX_VALID_LIFETIME])) { 1223 uint32_t time = parse_leasetime(c); 1224 1225 if (time > 0) 1226 iface->max_valid_lifetime = time; 1227 else 1228 error("Invalid %s value configured for interface '%s'", 1229 iface_attrs[IFACE_ATTR_MAX_VALID_LIFETIME].name, iface->name); 1230 } 1231 1232 if ((c = tb[IFACE_ATTR_DHCPV4_POOL_START])) { 1233 iface->dhcpv4_pool_start = blobmsg_get_u32(c); 1234 iface->dhcpv4_pool_end = iface->dhcpv4_pool_start + DHCPV4_POOL_LIMIT_DEFAULT - 1; 1235 } 1236 1237 if ((c = tb[IFACE_ATTR_DHCPV4_POOL_LIMIT])) 1238 iface->dhcpv4_pool_end = iface->dhcpv4_pool_start + blobmsg_get_u32(c) - 1; 1239 1240 if (iface->dhcpv4_pool_start > UINT16_MAX || 1241 iface->dhcpv4_pool_end > UINT16_MAX || 1242 iface->dhcpv4_pool_start > iface->dhcpv4_pool_end) { 1243 warn("Invalid DHCPv4 pool range for %s, disabling dynamic leases", iface->name); 1244 iface->no_dynamic_dhcp = true; 1245 } 1246 1247 if ((c = tb[IFACE_ATTR_MASTER])) 1248 iface->master = blobmsg_get_bool(c); 1249 1250 if (overwrite && (c = tb[IFACE_ATTR_UPSTREAM])) { 1251 struct blob_attr *cur; 1252 unsigned rem; 1253 char *tmp; 1254 1255 blobmsg_for_each_attr(cur, c, rem) { 1256 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1257 continue; 1258 1259 tmp = realloc(iface->upstream, iface->upstream_len + blobmsg_data_len(cur)); 1260 if (!tmp) 1261 goto err; 1262 1263 iface->upstream = tmp; 1264 memcpy(iface->upstream + iface->upstream_len, blobmsg_get_string(cur), blobmsg_data_len(cur)); 1265 iface->upstream_len += blobmsg_data_len(cur); 1266 } 1267 } 1268 1269 if ((c = tb[IFACE_ATTR_RA])) { 1270 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1271 iface->ra = mode; 1272 1273 if (iface->ra != MODE_DISABLED) 1274 iface->ignore = false; 1275 } else 1276 error("Invalid %s mode configured for interface '%s'", 1277 iface_attrs[IFACE_ATTR_RA].name, iface->name); 1278 } 1279 1280 if ((c = tb[IFACE_ATTR_DHCPV4])) { 1281 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1282 iface->dhcpv4 = config.main_dhcpv4 ? mode : MODE_DISABLED; 1283 1284 if (iface->dhcpv4 != MODE_DISABLED) 1285 iface->ignore = false; 1286 } else 1287 error("Invalid %s mode configured for interface %s", 1288 iface_attrs[IFACE_ATTR_DHCPV4].name, iface->name); 1289 } 1290 1291 if ((c = tb[IFACE_ATTR_DHCPV6])) { 1292 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1293 iface->dhcpv6 = mode; 1294 1295 if (iface->dhcpv6 != MODE_DISABLED) 1296 iface->ignore = false; 1297 } else 1298 error("Invalid %s mode configured for interface '%s'", 1299 iface_attrs[IFACE_ATTR_DHCPV6].name, iface->name); 1300 } 1301 1302 if ((c = tb[IFACE_ATTR_NDP])) { 1303 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1304 iface->ndp = mode; 1305 1306 if (iface->ndp != MODE_DISABLED) 1307 iface->ignore = false; 1308 } else 1309 error("Invalid %s mode configured for interface '%s'", 1310 iface_attrs[IFACE_ATTR_NDP].name, iface->name); 1311 } 1312 1313 if ((c = tb[IFACE_ATTR_ROUTER])) { 1314 struct blob_attr *cur; 1315 unsigned rem; 1316 1317 blobmsg_for_each_attr(cur, c, rem) { 1318 struct in_addr addr4, *tmp; 1319 1320 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1321 continue; 1322 1323 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 1324 tmp = realloc(iface->dhcpv4_routers, 1325 (iface->dhcpv4_routers_cnt + 1) * sizeof(*iface->dhcpv4_routers)); 1326 if (!tmp) 1327 goto err; 1328 1329 iface->dhcpv4_routers = tmp; 1330 iface->dhcpv4_routers[iface->dhcpv4_routers_cnt++] = addr4; 1331 } else { 1332 error("Invalid %s value configured for interface '%s'", 1333 iface_attrs[IFACE_ATTR_ROUTER].name, iface->name); 1334 } 1335 } 1336 } 1337 1338 if ((c = tb[IFACE_ATTR_CAPTIVE_PORTAL_URI])) { 1339 char *uri = strdup(blobmsg_get_string(c)); 1340 1341 if (!uri) { 1342 error("Out of memory parsing %s for interface '%s'", 1343 iface_attrs[IFACE_ATTR_CAPTIVE_PORTAL_URI].name, 1344 iface->name); 1345 goto err; 1346 } 1347 1348 iface->captive_portal_uri = uri; 1349 iface->captive_portal_uri_len = strlen(uri); 1350 if (iface->captive_portal_uri_len > UINT8_MAX) { 1351 warn("RFC8910 captive portal URI > %d characters for interface '%s': option via DHCPv4 not possible", 1352 UINT8_MAX, 1353 iface->name); 1354 } 1355 debug("Set RFC8910 captive portal URI: '%s' for interface '%s'", 1356 iface->captive_portal_uri, iface->name); 1357 } 1358 1359 if ((c = tb[IFACE_ATTR_DNS])) { 1360 struct blob_attr *cur; 1361 unsigned rem; 1362 1363 iface->always_rewrite_dns = true; 1364 blobmsg_for_each_attr(cur, c, rem) { 1365 struct in_addr addr4, *tmp4; 1366 struct in6_addr addr6, *tmp6; 1367 1368 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1369 continue; 1370 1371 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 1372 if (addr4.s_addr == INADDR_ANY) { 1373 error("Invalid %s value configured for interface '%s'", 1374 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 1375 continue; 1376 } 1377 1378 tmp4 = realloc(iface->dns_addrs4, (iface->dns_addrs4_cnt + 1) * 1379 sizeof(*iface->dns_addrs4)); 1380 if (!tmp4) 1381 goto err; 1382 1383 iface->dns_addrs4 = tmp4; 1384 iface->dns_addrs4[iface->dns_addrs4_cnt++] = addr4; 1385 1386 } else if (inet_pton(AF_INET6, blobmsg_get_string(cur), &addr6) == 1) { 1387 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { 1388 error("Invalid %s value configured for interface '%s'", 1389 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 1390 continue; 1391 } 1392 1393 tmp6 = realloc(iface->dns_addrs6, (iface->dns_addrs6_cnt + 1) * 1394 sizeof(*iface->dns_addrs6)); 1395 if (!tmp6) 1396 goto err; 1397 1398 iface->dns_addrs6 = tmp6; 1399 iface->dns_addrs6[iface->dns_addrs6_cnt++] = addr6; 1400 1401 } else { 1402 error("Invalid %s value configured for interface '%s'", 1403 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 1404 } 1405 } 1406 } 1407 1408 if ((c = tb[IFACE_ATTR_DNS_SERVICE])) 1409 iface->dns_service = blobmsg_get_bool(c); 1410 1411 if ((c = tb[IFACE_ATTR_DNS_DOMAIN_SEARCH])) { 1412 struct blob_attr *cur; 1413 unsigned rem; 1414 1415 blobmsg_for_each_attr(cur, c, rem) { 1416 uint8_t buf[DNS_MAX_NAME_LEN]; 1417 char *domain; 1418 size_t domainlen; 1419 int ds_len; 1420 uint8_t *tmp; 1421 1422 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1423 continue; 1424 1425 domain = blobmsg_get_string(cur); 1426 domainlen = strlen(domain); 1427 1428 if (domainlen > 0 && domain[domainlen - 1] == '.') 1429 domain[domainlen - 1] = 0; 1430 1431 ds_len = dn_comp(domain, buf, sizeof(buf), NULL, NULL); 1432 if (ds_len <= 0) { 1433 error("Invalid %s value configured for interface '%s'", 1434 iface_attrs[IFACE_ATTR_DNS_DOMAIN_SEARCH].name, iface->name); 1435 continue; 1436 } 1437 1438 tmp = realloc(iface->dns_search, iface->dns_search_len + ds_len); 1439 if (!tmp) 1440 goto err; 1441 1442 iface->dns_search = tmp; 1443 memcpy(&iface->dns_search[iface->dns_search_len], buf, ds_len); 1444 iface->dns_search_len += ds_len; 1445 } 1446 } 1447 1448 if ((c = tb[IFACE_ATTR_DHCPV4_FORCERECONF])) 1449 iface->dhcpv4_forcereconf = blobmsg_get_bool(c); 1450 1451 if ((c = tb[IFACE_ATTR_DHCPV6_RAW])) { 1452 void *tmp; 1453 size_t opt_len = blobmsg_data_len(c) / 2; 1454 1455 tmp = realloc(iface->dhcpv6_raw, opt_len); 1456 if (!tmp) 1457 goto err; 1458 1459 iface->dhcpv6_raw = tmp; 1460 iface->dhcpv6_raw_len = opt_len; 1461 odhcpd_unhexlify(iface->dhcpv6_raw, iface->dhcpv6_raw_len, blobmsg_get_string(c)); 1462 } 1463 1464 if ((c = tb[IFACE_ATTR_DHCPV6_ASSIGNALL])) 1465 iface->dhcpv6_assignall = blobmsg_get_bool(c); 1466 1467 if ((c = tb[IFACE_ATTR_DHCPV6_PD_PREFERRED])) 1468 iface->dhcpv6_pd_preferred = blobmsg_get_bool(c); 1469 1470 if ((c = tb[IFACE_ATTR_DHCPV6_PD])) 1471 iface->dhcpv6_pd = blobmsg_get_bool(c); 1472 1473 if ((c = tb[IFACE_ATTR_DHCPV6_PD_MIN_LEN])) { 1474 uint32_t pd_min_len = blobmsg_get_u32(c); 1475 1476 if (pd_min_len > PD_MIN_LEN_MAX) { 1477 pd_min_len = PD_MIN_LEN_MAX; 1478 warn("Clamped invalid %s value configured for interface '%s' to %d", 1479 iface_attrs[IFACE_ATTR_DHCPV6_PD_MIN_LEN].name, iface->name, pd_min_len); 1480 } 1481 1482 iface->dhcpv6_pd_min_len = pd_min_len; 1483 } 1484 1485 if ((c = tb[IFACE_ATTR_DHCPV6_NA])) 1486 iface->dhcpv6_na = blobmsg_get_bool(c); 1487 1488 if ((c = tb[IFACE_ATTR_DHCPV6_HOSTID_LEN])) { 1489 uint32_t original_hostid_len, hostid_len; 1490 original_hostid_len = hostid_len = blobmsg_get_u32(c); 1491 1492 if (hostid_len < HOSTID_LEN_MIN) 1493 hostid_len = HOSTID_LEN_MIN; 1494 else if (hostid_len > HOSTID_LEN_MAX) 1495 hostid_len = HOSTID_LEN_MAX; 1496 1497 iface->dhcpv6_hostid_len = hostid_len; 1498 1499 if (original_hostid_len != hostid_len) { 1500 warn("Clamped invalid %s value configured for interface '%s' to %d", 1501 iface_attrs[IFACE_ATTR_DHCPV6_HOSTID_LEN].name, iface->name, iface->dhcpv6_hostid_len); 1502 } 1503 } 1504 1505 if ((c = tb[IFACE_ATTR_RA_DEFAULT])) 1506 iface->default_router = blobmsg_get_u32(c); 1507 1508 if ((c = tb[IFACE_ATTR_RA_FLAGS])) { 1509 iface->ra_flags = 0; 1510 1511 if (parse_ra_flags(&iface->ra_flags, c) < 0) 1512 error("Invalid %s value configured for interface '%s'", 1513 iface_attrs[IFACE_ATTR_RA_FLAGS].name, iface->name); 1514 } 1515 1516 if ((c = tb[IFACE_ATTR_RA_REACHABLETIME])) { 1517 uint32_t ra_reachabletime = blobmsg_get_u32(c); 1518 1519 /* RFC4861 §6.2.1 : AdvReachableTime : 1520 * MUST be no greater than 3,600,000 msec 1521 */ 1522 iface->ra_reachabletime = ra_reachabletime <= AdvReachableTime ? ra_reachabletime : AdvReachableTime; 1523 if(ra_reachabletime > AdvReachableTime) 1524 warn("Clamped invalid %s value configured for interface '%s' to %d", 1525 iface_attrs[IFACE_ATTR_RA_REACHABLETIME].name, iface->name, iface->ra_reachabletime); 1526 } 1527 1528 if ((c = tb[IFACE_ATTR_RA_RETRANSTIME])) { 1529 uint32_t ra_retranstime = blobmsg_get_u32(c); 1530 1531 iface->ra_retranstime = ra_retranstime <= RETRANS_TIMER_MAX ? ra_retranstime : RETRANS_TIMER_MAX; 1532 if (ra_retranstime > RETRANS_TIMER_MAX) 1533 warn("Clamped invalid %s value configured for interface '%s' to %d", 1534 iface_attrs[IFACE_ATTR_RA_RETRANSTIME].name, iface->name, iface->ra_retranstime); 1535 } 1536 1537 if ((c = tb[IFACE_ATTR_RA_HOPLIMIT])) { 1538 uint32_t ra_hoplimit = blobmsg_get_u32(c); 1539 1540 /* RFC4861 §6.2.1 : AdvCurHopLimit */ 1541 iface->ra_hoplimit = ra_hoplimit <= AdvCurHopLimit ? ra_hoplimit : AdvCurHopLimit; 1542 if(ra_hoplimit > AdvCurHopLimit) 1543 warn("Clamped invalid %s value configured for interface '%s' to %d", 1544 iface_attrs[IFACE_ATTR_RA_HOPLIMIT].name, iface->name, iface->ra_hoplimit); 1545 } 1546 1547 iface->if_mtu = odhcpd_get_interface_config(iface->ifname, "mtu"); 1548 if ((c = tb[IFACE_ATTR_RA_MTU])) { 1549 uint32_t original_ra_mtu, ra_mtu; 1550 original_ra_mtu = ra_mtu = blobmsg_get_u32(c); 1551 if (ra_mtu < RA_MTU_MIN) 1552 ra_mtu = RA_MTU_MIN; 1553 else if (ra_mtu > RA_MTU_MAX) 1554 ra_mtu = RA_MTU_MAX; 1555 if (iface->if_mtu && ra_mtu > iface->if_mtu) 1556 ra_mtu = iface->if_mtu; 1557 1558 iface->ra_mtu = ra_mtu; 1559 1560 if (original_ra_mtu != ra_mtu) { 1561 warn("Clamped invalid %s value configured for interface '%s' to %d", 1562 iface_attrs[IFACE_ATTR_RA_MTU].name, iface->name, iface->ra_mtu); 1563 } 1564 } 1565 1566 /* Default RA MTU to the interface MTU if no value is assigned */ 1567 if (!iface->ra_mtu && iface->if_mtu) { 1568 iface->ra_mtu = iface->if_mtu; 1569 info("Defaulted %s value for interface '%s' to %d", 1570 iface_attrs[IFACE_ATTR_RA_MTU].name, iface->name, iface->ra_mtu); 1571 } 1572 1573 if ((c = tb[IFACE_ATTR_RA_SLAAC])) 1574 iface->ra_slaac = blobmsg_get_bool(c); 1575 1576 if ((c = tb[IFACE_ATTR_RA_OFFLINK])) 1577 iface->ra_not_onlink = blobmsg_get_bool(c); 1578 1579 if ((c = tb[IFACE_ATTR_RA_ADVROUTER])) 1580 iface->ra_advrouter = blobmsg_get_bool(c); 1581 1582 /* 1583 * RFC4861: MaxRtrAdvInterval: MUST be no less than 4 seconds and no greater than 1800 seconds. 1584 * RFC8319: MaxRtrAdvInterval: MUST be no less than 4 seconds and no greater than 65535 seconds. 1585 * Default: 600 seconds 1586 */ 1587 if ((c = tb[IFACE_ATTR_RA_MAXINTERVAL])){ 1588 uint32_t ra_maxinterval = blobmsg_get_u32(c); 1589 if (ra_maxinterval < 4) 1590 ra_maxinterval = 4; 1591 else if (ra_maxinterval > MaxRtrAdvInterval) 1592 ra_maxinterval = MaxRtrAdvInterval; 1593 iface->ra_maxinterval = ra_maxinterval; 1594 } 1595 1596 /* 1597 * RFC4861: MinRtrAdvInterval: MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. 1598 * Default: 0.33 * MaxRtrAdvInterval If MaxRtrAdvInterval >= 9 seconds; otherwise, the 1599 * Default is MaxRtrAdvInterval. 1600 */ 1601 if ((c = tb[IFACE_ATTR_RA_MININTERVAL])){ 1602 uint32_t ra_mininterval = blobmsg_get_u32(c); 1603 if (ra_mininterval < MinRtrAdvInterval) 1604 ra_mininterval = MinRtrAdvInterval; // clamp min 1605 else if (ra_mininterval > (0.75 * iface->ra_maxinterval)) 1606 ra_mininterval = 0.75 * iface->ra_maxinterval; // clamp max 1607 iface->ra_mininterval = ra_mininterval; 1608 } 1609 1610 /* 1611 * RFC4861: AdvDefaultLifetime: MUST be either zero or between MaxRtrAdvInterval and 9000 seconds. 1612 * RFC8319: AdvDefaultLifetime: MUST be either zero or between MaxRtrAdvInterval and 65535 seconds. 1613 * Default: 3 * MaxRtrAdvInterval 1614 * i.e. 3 * 65535 => 65535 seconds. 1615 */ 1616 if ((c = tb[IFACE_ATTR_RA_LIFETIME])){ 1617 uint32_t ra_lifetime = blobmsg_get_u32(c); 1618 if (ra_lifetime != 0){ 1619 if (ra_lifetime < iface->ra_maxinterval) 1620 ra_lifetime = iface->ra_maxinterval; // clamp min 1621 else if (ra_lifetime > AdvDefaultLifetime) 1622 ra_lifetime = AdvDefaultLifetime; // clamp max 1623 } 1624 iface->ra_lifetime = ra_lifetime; 1625 } 1626 1627 if ((c = tb[IFACE_ATTR_RA_DNS])) 1628 iface->ra_dns = blobmsg_get_bool(c); 1629 1630 if ((c = tb[IFACE_ATTR_DNR])) { 1631 struct blob_attr *cur; 1632 unsigned rem; 1633 1634 blobmsg_for_each_attr(cur, c, rem) { 1635 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1636 continue; 1637 1638 if (parse_dnr_str(blobmsg_get_string(cur), iface)) 1639 error("Invalid %s value configured for interface '%s'", 1640 iface_attrs[IFACE_ATTR_DNR].name, iface->name); 1641 } 1642 } 1643 1644 if ((c = tb[IFACE_ATTR_RA_PREF64])) { 1645 struct in6_addr addr; 1646 1647 odhcpd_parse_addr6_prefix(blobmsg_get_string(c), 1648 &addr, &iface->pref64_length); 1649 1650 iface->pref64_prefix[0] = addr.s6_addr32[0]; 1651 switch (iface->pref64_length) { 1652 case 96: 1653 iface->pref64_plc = 0; 1654 iface->pref64_prefix[1] = addr.s6_addr32[1]; 1655 iface->pref64_prefix[2] = addr.s6_addr32[2]; 1656 break; 1657 case 64: 1658 iface->pref64_plc = 1; 1659 iface->pref64_prefix[1] = addr.s6_addr32[1]; 1660 iface->pref64_prefix[2] = 0; 1661 break; 1662 case 56: 1663 iface->pref64_plc = 2; 1664 iface->pref64_prefix[1] = addr.s6_addr32[1] & htonl(0xffffff00); 1665 iface->pref64_prefix[2] = 0; 1666 break; 1667 case 48: 1668 iface->pref64_plc = 3; 1669 iface->pref64_prefix[1] = addr.s6_addr32[1] & htonl(0xffff0000); 1670 iface->pref64_prefix[2] = 0; 1671 break; 1672 case 40: 1673 iface->pref64_plc = 4; 1674 iface->pref64_prefix[1] = addr.s6_addr32[1] & htonl(0xff000000); 1675 iface->pref64_prefix[2] = 0; 1676 break; 1677 case 32: 1678 iface->pref64_plc = 5; 1679 iface->pref64_prefix[1] = 0; 1680 iface->pref64_prefix[2] = 0; 1681 break; 1682 default: 1683 warn("Invalid PREF64 prefix size (%d), ignoring ra_pref64 option!", 1684 iface->pref64_length); 1685 iface->pref64_length = 0; 1686 } 1687 } 1688 1689 if ((c = tb[IFACE_ATTR_IPV6_ONLY_PREFERRED])) { 1690 uint32_t v6only_wait = blobmsg_get_u32(c); 1691 1692 if (v6only_wait > 0 && v6only_wait < DHCPV4_MIN_V6ONLY_WAIT) { 1693 warn("Invalid %s value configured for interface '%s', clamped to %d", 1694 iface_attrs[IFACE_ATTR_IPV6_ONLY_PREFERRED].name, 1695 iface->name, DHCPV4_MIN_V6ONLY_WAIT); 1696 v6only_wait = DHCPV4_MIN_V6ONLY_WAIT; 1697 } 1698 1699 iface->dhcpv4_v6only_wait = v6only_wait; 1700 } 1701 1702 if ((c = tb[IFACE_ATTR_RA_PREFERENCE])) { 1703 const char *prio = blobmsg_get_string(c); 1704 1705 if (!strcmp(prio, "high")) 1706 iface->route_preference = 1; 1707 else if (!strcmp(prio, "low")) 1708 iface->route_preference = -1; 1709 else if (!strcmp(prio, "medium") || !strcmp(prio, "default")) 1710 iface->route_preference = 0; 1711 else 1712 error("Invalid %s mode configured for interface '%s'", 1713 iface_attrs[IFACE_ATTR_RA_PREFERENCE].name, iface->name); 1714 } 1715 1716 if ((c = tb[IFACE_ATTR_NDPROXY_ROUTING])) 1717 iface->learn_routes = blobmsg_get_bool(c); 1718 1719 if ((c = tb[IFACE_ATTR_NDPROXY_SLAVE])) 1720 iface->external = blobmsg_get_bool(c); 1721 1722 if ((c = tb[IFACE_ATTR_NDP_FROM_LINK_LOCAL])) 1723 iface->ndp_from_link_local = blobmsg_get_bool(c); 1724 1725 if ((c = tb[IFACE_ATTR_PREFIX_FILTER])) 1726 odhcpd_parse_addr6_prefix(blobmsg_get_string(c), 1727 &iface->pio_filter_addr, 1728 &iface->pio_filter_length); 1729 1730 if (overwrite && (c = tb[IFACE_ATTR_DHCPV6_RELAY_SERVERS])) { 1731 struct blob_attr *cur; 1732 unsigned rem; 1733 1734 blobmsg_for_each_attr(cur, c, rem) { 1735 struct in6_addr addr6, *tmp6; 1736 1737 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1738 continue; 1739 1740 if (inet_pton(AF_INET6, blobmsg_get_string(cur), &addr6) == 1) { 1741 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { 1742 error("Invalid %s value configured for interface '%s'", 1743 iface_attrs[IFACE_ATTR_DHCPV6_RELAY_SERVERS].name, iface->name); 1744 continue; 1745 } 1746 1747 tmp6 = realloc(iface->dhcpv6_relay_server_addrs6, 1748 (iface->dhcpv6_relay_server_addrs6_cnt + 1) * 1749 sizeof(*iface->dhcpv6_relay_server_addrs6)); 1750 1751 if (!tmp6) 1752 goto err; 1753 1754 iface->dhcpv6_relay_server_addrs6 = tmp6; 1755 iface->dhcpv6_relay_server_addrs6[iface->dhcpv6_relay_server_addrs6_cnt++] = addr6; 1756 } else { 1757 error("Invalid %s value configured for interface '%s'", 1758 iface_attrs[IFACE_ATTR_DHCPV6_RELAY_SERVERS].name, iface->name); 1759 } 1760 } 1761 } 1762 1763 if (overwrite && (c = tb[IFACE_ATTR_NTP])) { 1764 struct blob_attr *cur; 1765 unsigned rem; 1766 1767 blobmsg_for_each_attr(cur, c, rem) { 1768 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1769 continue; 1770 1771 char *str = blobmsg_get_string(cur); 1772 struct in_addr addr4, *tmp4; 1773 struct in6_addr addr6, *tmp6; 1774 1775 if (inet_pton(AF_INET, str, &addr4) == 1) { 1776 if (addr4.s_addr == INADDR_ANY) 1777 goto err; 1778 1779 tmp4 = realloc(iface->dhcpv4_ntp, (iface->dhcpv4_ntp_cnt + 1) * sizeof(*iface->dhcpv4_ntp)); 1780 if (!tmp4) 1781 goto err; 1782 1783 iface->dhcpv4_ntp = tmp4; 1784 iface->dhcpv4_ntp[iface->dhcpv4_ntp_cnt++] = addr4; 1785 1786 } else if (inet_pton(AF_INET6, str, &addr6) == 1) { 1787 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) 1788 goto err; 1789 1790 tmp6 = realloc(iface->dhcpv6_sntp, (iface->dhcpv6_sntp_cnt + 1) * sizeof(*iface->dhcpv6_sntp)); 1791 if (!tmp6) 1792 goto err; 1793 1794 iface->dhcpv6_sntp = tmp6; 1795 iface->dhcpv6_sntp[iface->dhcpv6_sntp_cnt++] = addr6; 1796 1797 if (!parse_ntp_options(&iface->dhcpv6_ntp_len, addr6, &iface->dhcpv6_ntp)) 1798 iface->dhcpv6_ntp_cnt++; 1799 1800 } else { 1801 if (!parse_ntp_fqdn(&iface->dhcpv6_ntp_len, str, &iface->dhcpv6_ntp)) 1802 iface->dhcpv6_ntp_cnt++; 1803 } 1804 } 1805 } 1806 1807 statefiles_read_prefix_information(iface); 1808 1809 return 0; 1810 1811 err: 1812 close_interface(iface); 1813 return -1; 1814 } 1815 1816 static int set_interface(struct uci_section *s) 1817 { 1818 blob_buf_init(&b, 0); 1819 uci_to_blob(&b, s, &interface_attr_list); 1820 1821 return config_parse_interface(blob_data(b.head), blob_len(b.head), s->e.name, true); 1822 } 1823 1824 static void lease_cfg_delete_dhcpv6_leases(struct lease_cfg *lease_cfg) 1825 { 1826 struct dhcpv6_lease *lease, *tmp; 1827 1828 list_for_each_entry_safe(lease, tmp, &lease_cfg->dhcpv6_leases, lease_cfg_list) 1829 dhcpv6_free_lease(lease); 1830 } 1831 1832 static void lease_cfg_update_leases(struct lease_cfg *lease_cfg) 1833 { 1834 struct dhcpv4_lease *lease4 = lease_cfg->dhcpv4_lease; 1835 struct dhcpv6_lease *lease6; 1836 1837 if (lease4) { 1838 free(lease4->hostname); 1839 lease4->hostname = NULL; 1840 1841 if (lease_cfg->hostname) { 1842 lease4->hostname = strdup(lease_cfg->hostname); 1843 lease4->hostname_valid = true; 1844 } 1845 } 1846 1847 list_for_each_entry(lease6, &lease_cfg->dhcpv6_leases, lease_cfg_list) { 1848 free(lease6->hostname); 1849 lease6->hostname = NULL; 1850 1851 if (lease_cfg->hostname) { 1852 lease6->hostname = strdup(lease_cfg->hostname); 1853 lease6->hostname_valid = true; 1854 } 1855 1856 lease6->leasetime = lease_cfg->leasetime; 1857 } 1858 } 1859 1860 static int lease_cfg_cmp(const void *k1, const void *k2, _o_unused void *ptr) 1861 { 1862 const struct lease_cfg *lease_cfg1 = k1, *lease_cfg2 = k2; 1863 int cmp = 0; 1864 1865 if (lease_cfg1->duid_count != lease_cfg2->duid_count) 1866 return lease_cfg1->duid_count - lease_cfg2->duid_count; 1867 1868 for (size_t i = 0; i < lease_cfg1->duid_count; i++) { 1869 if (lease_cfg1->duids[i].len != lease_cfg2->duids[i].len) 1870 return lease_cfg1->duids[i].len - lease_cfg2->duids[i].len; 1871 1872 if (lease_cfg1->duids[i].len && lease_cfg2->duids[i].len) { 1873 cmp = memcmp(lease_cfg1->duids[i].id, lease_cfg2->duids[i].id, 1874 lease_cfg1->duids[i].len); 1875 if (cmp) 1876 return cmp; 1877 } 1878 } 1879 1880 if (lease_cfg1->mac_count != lease_cfg2->mac_count) 1881 return lease_cfg1->mac_count - lease_cfg2->mac_count; 1882 1883 for (size_t i = 0; i < lease_cfg1->mac_count; i++) { 1884 cmp = memcmp(lease_cfg1->macs[i].ether_addr_octet, 1885 lease_cfg2->macs[i].ether_addr_octet, 1886 sizeof(lease_cfg1->macs[i].ether_addr_octet)); 1887 if (cmp) 1888 return cmp; 1889 } 1890 1891 return 0; 1892 } 1893 1894 static void lease_cfg_change(struct lease_cfg *lease_cfg_old, struct lease_cfg *lease_cfg_new) 1895 { 1896 bool update = false; 1897 1898 if ((!!lease_cfg_new->hostname != !!lease_cfg_old->hostname) || 1899 (lease_cfg_new->hostname && strcmp(lease_cfg_new->hostname, lease_cfg_old->hostname))) { 1900 free(lease_cfg_old->hostname); 1901 lease_cfg_old->hostname = NULL; 1902 1903 if (lease_cfg_new->hostname) 1904 lease_cfg_old->hostname = strdup(lease_cfg_new->hostname); 1905 1906 update = true; 1907 } 1908 1909 if (lease_cfg_old->leasetime != lease_cfg_new->leasetime) { 1910 lease_cfg_old->leasetime = lease_cfg_new->leasetime; 1911 update = true; 1912 } 1913 1914 if (lease_cfg_old->ipv4.s_addr != lease_cfg_new->ipv4.s_addr) { 1915 lease_cfg_old->ipv4 = lease_cfg_new->ipv4; 1916 dhcpv4_free_lease(lease_cfg_old->dhcpv4_lease); 1917 } 1918 1919 if (lease_cfg_old->hostid != lease_cfg_new->hostid) { 1920 lease_cfg_old->hostid = lease_cfg_new->hostid; 1921 lease_cfg_delete_dhcpv6_leases(lease_cfg_old); 1922 } 1923 1924 if (update) 1925 lease_cfg_update_leases(lease_cfg_old); 1926 1927 free_lease_cfg(lease_cfg_new); 1928 } 1929 1930 static void lease_cfg_delete(struct lease_cfg *lease_cfg) 1931 { 1932 dhcpv4_free_lease(lease_cfg->dhcpv4_lease); 1933 lease_cfg_delete_dhcpv6_leases(lease_cfg); 1934 free_lease_cfg(lease_cfg); 1935 } 1936 1937 static void lease_cfg_update(_o_unused struct vlist_tree *tree, struct vlist_node *node_new, 1938 struct vlist_node *node_old) 1939 { 1940 struct lease_cfg *lease_cfg_new = container_of(node_new, struct lease_cfg, node); 1941 struct lease_cfg *lease_cfg_old = container_of(node_old, struct lease_cfg, node); 1942 1943 if (node_old && node_new) 1944 lease_cfg_change(lease_cfg_old, lease_cfg_new); 1945 else if (node_old) 1946 lease_cfg_delete(lease_cfg_old); 1947 } 1948 1949 /* 1950 * Either find: 1951 * a) a lease cfg with an exact DUID/IAID match; or 1952 * b) a lease cfg with a matching DUID and no IAID set 1953 */ 1954 struct lease_cfg * 1955 config_find_lease_cfg_by_duid_and_iaid(const uint8_t *duid, const uint16_t len, const uint32_t iaid) 1956 { 1957 struct lease_cfg *lease_cfg, *candidate = NULL; 1958 1959 vlist_for_each_element(&lease_cfgs, lease_cfg, node) { 1960 for (size_t i = 0; i < lease_cfg->duid_count; i++) { 1961 if (lease_cfg->duids[i].len != len) 1962 continue; 1963 1964 if (memcmp(lease_cfg->duids[i].id, duid, len)) 1965 continue; 1966 1967 if (!lease_cfg->duids[i].iaid_set) { 1968 candidate = lease_cfg; 1969 continue; 1970 } 1971 1972 if (lease_cfg->duids[i].iaid == iaid) 1973 return lease_cfg; 1974 } 1975 } 1976 1977 return candidate; 1978 } 1979 1980 struct lease_cfg *config_find_lease_cfg_by_mac(const uint8_t *mac) 1981 { 1982 struct lease_cfg *lease_cfg; 1983 1984 vlist_for_each_element(&lease_cfgs, lease_cfg, node) { 1985 for (size_t i = 0; i < lease_cfg->mac_count; i++) { 1986 if (!memcmp(lease_cfg->macs[i].ether_addr_octet, mac, 1987 sizeof(lease_cfg->macs[i].ether_addr_octet))) 1988 return lease_cfg; 1989 } 1990 } 1991 1992 return NULL; 1993 } 1994 1995 struct lease_cfg *config_find_lease_cfg_by_hostid(const uint64_t hostid) 1996 { 1997 struct lease_cfg *lease_cfg; 1998 1999 vlist_for_each_element(&lease_cfgs, lease_cfg, node) { 2000 if (lease_cfg->hostid == hostid) 2001 return lease_cfg; 2002 } 2003 2004 return NULL; 2005 } 2006 2007 struct lease_cfg *config_find_lease_cfg_by_ipv4(const struct in_addr ipv4) 2008 { 2009 struct lease_cfg *lease_cfg; 2010 2011 vlist_for_each_element(&lease_cfgs, lease_cfg, node) { 2012 if (lease_cfg->ipv4.s_addr == ipv4.s_addr) 2013 return lease_cfg; 2014 } 2015 2016 return NULL; 2017 } 2018 2019 void reload_services(struct interface *iface) 2020 { 2021 if (iface->ifflags & IFF_RUNNING) { 2022 debug("Enabling services with %s running", iface->ifname); 2023 router_setup_interface(iface, iface->ra != MODE_DISABLED); 2024 dhcpv6_setup_interface(iface, iface->dhcpv6 != MODE_DISABLED); 2025 ndp_setup_interface(iface, iface->ndp != MODE_DISABLED); 2026 dhcpv4_setup_interface(iface, iface->dhcpv4 != MODE_DISABLED); 2027 } else { 2028 debug("Disabling services with %s not running", iface->ifname); 2029 router_setup_interface(iface, false); 2030 dhcpv6_setup_interface(iface, false); 2031 ndp_setup_interface(iface, false); 2032 dhcpv4_setup_interface(iface, false); 2033 } 2034 } 2035 2036 static int ipv6_pxe_from_uci(struct uci_section* s) 2037 { 2038 blob_buf_init(&b, 0); 2039 uci_to_blob(&b, s, &ipv6_pxe_attr_list); 2040 2041 void* data = blob_data(b.head); 2042 size_t len = blob_len(b.head); 2043 2044 struct blob_attr* tb[IFACE_ATTR_MAX]; 2045 blobmsg_parse(ipv6_pxe_attrs, IPV6_PXE_MAX, tb, data, len); 2046 2047 if (!tb[IPV6_PXE_URL]) 2048 return -1; 2049 2050 const char* url = blobmsg_get_string(tb[IPV6_PXE_URL]); 2051 2052 uint32_t arch = 0xFFFFFFFF; 2053 if (tb[IPV6_PXE_ARCH]) 2054 arch = blobmsg_get_u32(tb[IPV6_PXE_ARCH]); 2055 2056 /* ipv6_pxe_entry_new() returns the new entry on success and NULL on 2057 * allocation failure. Mirror that into the int return code the rest 2058 * of the module uses: success -> 0, failure -> -1. */ 2059 return ipv6_pxe_entry_new(arch, url) ? 0 : -1; 2060 } 2061 2062 void odhcpd_reload(void) 2063 { 2064 struct uci_context *uci = uci_alloc_context(); 2065 struct interface *master = NULL, *i, *tmp; 2066 char *uci_dhcp_path = "dhcp"; 2067 char *uci_system_path = "system"; 2068 char *uci_network_path = "network"; 2069 2070 if (!uci) 2071 return; 2072 2073 if (config.uci_cfgdir) { 2074 size_t dlen = strlen(config.uci_cfgdir); 2075 2076 uci_dhcp_path = alloca(dlen + sizeof("/dhcp")); 2077 sprintf(uci_dhcp_path, "%s/dhcp", config.uci_cfgdir); 2078 uci_system_path = alloca(dlen + sizeof("/system")); 2079 sprintf(uci_system_path, "%s/system", config.uci_cfgdir); 2080 uci_network_path = alloca(dlen + sizeof("/network")); 2081 sprintf(uci_network_path, "%s/network", config.uci_cfgdir); 2082 } 2083 2084 vlist_update(&lease_cfgs); 2085 avl_for_each_element(&interfaces, i, avl) 2086 clean_interface(i); 2087 2088 struct uci_package *network = NULL; 2089 if (!uci_load(uci, uci_network_path, &network)) { 2090 struct uci_element *e; 2091 2092 /* 0. Global settings */ 2093 uci_foreach_element(&network->sections, e) { 2094 struct uci_section *s = uci_to_section(e); 2095 if (!strcmp(s->type, "globals")) 2096 set_global_config(s); 2097 } 2098 } 2099 uci_unload(uci, network); 2100 2101 struct uci_package *dhcp = NULL; 2102 if (!uci_load(uci, uci_dhcp_path, &dhcp)) { 2103 struct uci_element *e; 2104 2105 /* 1. General odhcpd settings */ 2106 uci_foreach_element(&dhcp->sections, e) { 2107 struct uci_section *s = uci_to_section(e); 2108 if (!strcmp(s->type, "odhcpd")) 2109 set_config(s); 2110 } 2111 2112 /* 2. DHCP pools */ 2113 uci_foreach_element(&dhcp->sections, e) { 2114 struct uci_section *s = uci_to_section(e); 2115 if (!strcmp(s->type, "dhcp")) 2116 set_interface(s); 2117 } 2118 2119 /* 3. Static lease cfgs */ 2120 uci_foreach_element(&dhcp->sections, e) { 2121 struct uci_section* s = uci_to_section(e); 2122 if (!strcmp(s->type, "host")) 2123 set_lease_cfg_from_uci(s); 2124 } 2125 2126 /* 4. IPv6 PxE */ 2127 ipv6_pxe_clear(); 2128 uci_foreach_element(&dhcp->sections, e) { 2129 struct uci_section* s = uci_to_section(e); 2130 if (!strcmp(s->type, "boot6")) 2131 ipv6_pxe_from_uci(s); 2132 } 2133 ipv6_pxe_dump(); 2134 } 2135 uci_unload(uci, dhcp); 2136 2137 struct uci_package *system = NULL; 2138 if (config.enable_tz && !uci_load(uci, uci_system_path, &system)) { 2139 struct uci_element *e; 2140 2141 /* 5. System settings */ 2142 uci_foreach_element(&system->sections, e) { 2143 struct uci_section *s = uci_to_section(e); 2144 if (!strcmp(s->type, "system")) 2145 set_timezone_info_from_uci(s); 2146 } 2147 } 2148 uci_unload(uci, system); 2149 2150 vlist_flush(&lease_cfgs); 2151 2152 ubus_apply_network(); 2153 2154 bool any_dhcpv6_slave = false, any_ra_slave = false, any_ndp_slave = false; 2155 2156 /* Test for */ 2157 avl_for_each_element(&interfaces, i, avl) { 2158 if (i->master) 2159 continue; 2160 2161 if (i->dhcpv6 == MODE_HYBRID || i->dhcpv6 == MODE_RELAY) 2162 any_dhcpv6_slave = true; 2163 2164 if (i->ra == MODE_HYBRID || i->ra == MODE_RELAY) 2165 any_ra_slave = true; 2166 2167 if (i->ndp == MODE_HYBRID || i->ndp == MODE_RELAY) 2168 any_ndp_slave = true; 2169 } 2170 2171 /* Evaluate hybrid mode for master */ 2172 avl_for_each_element(&interfaces, i, avl) { 2173 if (!i->master) 2174 continue; 2175 2176 enum odhcpd_mode hybrid_mode = MODE_DISABLED; 2177 2178 if (config.use_ubus && !ubus_has_prefix(i->name, i->ifname)) 2179 hybrid_mode = MODE_RELAY; 2180 2181 if (i->dhcpv6 == MODE_HYBRID) 2182 i->dhcpv6 = hybrid_mode; 2183 2184 if (i->dhcpv6 == MODE_RELAY && !any_dhcpv6_slave) 2185 i->dhcpv6 = MODE_DISABLED; 2186 2187 if (i->ra == MODE_HYBRID) 2188 i->ra = hybrid_mode; 2189 2190 if (i->ra == MODE_RELAY && !any_ra_slave) 2191 i->ra = MODE_DISABLED; 2192 2193 if (i->ndp == MODE_HYBRID) 2194 i->ndp = hybrid_mode; 2195 2196 if (i->ndp == MODE_RELAY && !any_ndp_slave) 2197 i->ndp = MODE_DISABLED; 2198 2199 if (i->dhcpv6 == MODE_RELAY || i->ra == MODE_RELAY || i->ndp == MODE_RELAY) 2200 master = i; 2201 } 2202 2203 2204 avl_for_each_element_safe(&interfaces, i, avl, tmp) { 2205 if (i->inuse && i->ifflags & IFF_RUNNING) { 2206 /* Resolve hybrid mode */ 2207 if (i->dhcpv6 == MODE_HYBRID) 2208 i->dhcpv6 = (master && master->dhcpv6 == MODE_RELAY) ? 2209 MODE_RELAY : MODE_SERVER; 2210 2211 if (i->ra == MODE_HYBRID) 2212 i->ra = (master && master->ra == MODE_RELAY) ? 2213 MODE_RELAY : MODE_SERVER; 2214 2215 if (i->ndp == MODE_HYBRID) 2216 i->ndp = (master && master->ndp == MODE_RELAY) ? 2217 MODE_RELAY : MODE_DISABLED; 2218 2219 reload_services(i); 2220 } else 2221 close_interface(i); 2222 } 2223 2224 uci_free_context(uci); 2225 } 2226 2227 static void signal_reload(_o_unused struct uloop_signal *signal) 2228 { 2229 odhcpd_reload(); 2230 } 2231 2232 int odhcpd_run(void) 2233 { 2234 static struct uloop_signal sighup = { .signo = SIGHUP, .cb = signal_reload }; 2235 2236 if (config.use_ubus) { 2237 while (ubus_init()) { 2238 if (uloop_cancelled) 2239 return EXIT_FAILURE; 2240 sleep(1); 2241 } 2242 } 2243 2244 odhcpd_reload(); 2245 2246 /* uloop_init() already handles SIGINT/SIGTERM */ 2247 if (uloop_signal_add(&sighup) < 0) 2248 return EXIT_FAILURE; 2249 2250 uloop_run(); 2251 2252 return EXIT_SUCCESS; 2253 } 2254
This page was automatically generated by LXR 0.3.1. • OpenWrt