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 <syslog.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 "dhcpv6-pxe.h" 22 23 static struct blob_buf b; 24 static int reload_pipe[2] = { -1, -1 }; 25 26 static int lease_cmp(const void *k1, const void *k2, void *ptr); 27 static void lease_update(struct vlist_tree *tree, struct vlist_node *node_new, 28 struct vlist_node *node_old); 29 30 struct vlist_tree leases = VLIST_TREE_INIT(leases, lease_cmp, lease_update, true, false); 31 AVL_TREE(interfaces, avl_strcmp, false, NULL); 32 struct config config = {.legacy = false, .main_dhcpv4 = false, 33 .dhcp_cb = NULL, .dhcp_statefile = NULL, .dhcp_hostsfile = NULL, 34 .log_level = LOG_WARNING}; 35 36 #define START_DEFAULT 100 37 #define LIMIT_DEFAULT 150 38 39 #define HOSTID_LEN_MIN 12 40 #define HOSTID_LEN_MAX 64 41 #define HOSTID_LEN_DEFAULT HOSTID_LEN_MIN 42 43 #define PD_MIN_LEN_MAX (64-2) // must delegate at least 2 bits of prefix 44 45 #define OAF_DHCPV6 (OAF_DHCPV6_NA | OAF_DHCPV6_PD) 46 47 enum { 48 IPV6_PXE_URL, 49 IPV6_PXE_ARCH, 50 IPV6_PXE_MAX 51 }; 52 53 static const struct blobmsg_policy ipv6_pxe_attrs[IPV6_PXE_MAX] = { 54 [IPV6_PXE_URL] = {.name = "url", .type = BLOBMSG_TYPE_STRING }, 55 [IPV6_PXE_ARCH] = {.name = "arch", .type = BLOBMSG_TYPE_INT32 }, 56 }; 57 58 const struct uci_blob_param_list ipv6_pxe_attr_list = { 59 .n_params = IPV6_PXE_MAX, 60 .params = ipv6_pxe_attrs, 61 }; 62 63 enum { 64 IFACE_ATTR_INTERFACE, 65 IFACE_ATTR_IFNAME, 66 IFACE_ATTR_NETWORKID, 67 IFACE_ATTR_DYNAMICDHCP, 68 IFACE_ATTR_LEASETIME, 69 IFACE_ATTR_LIMIT, 70 IFACE_ATTR_START, 71 IFACE_ATTR_MASTER, 72 IFACE_ATTR_UPSTREAM, 73 IFACE_ATTR_RA, 74 IFACE_ATTR_DHCPV4, 75 IFACE_ATTR_DHCPV6, 76 IFACE_ATTR_NDP, 77 IFACE_ATTR_ROUTER, 78 IFACE_ATTR_DNS, 79 IFACE_ATTR_DNR, 80 IFACE_ATTR_DNS_SERVICE, 81 IFACE_ATTR_DOMAIN, 82 IFACE_ATTR_FILTER_CLASS, 83 IFACE_ATTR_DHCPV4_FORCERECONF, 84 IFACE_ATTR_DHCPV6_RAW, 85 IFACE_ATTR_DHCPV6_ASSIGNALL, 86 IFACE_ATTR_DHCPV6_PD, 87 IFACE_ATTR_DHCPV6_PD_MIN_LEN, 88 IFACE_ATTR_DHCPV6_NA, 89 IFACE_ATTR_DHCPV6_HOSTID_LEN, 90 IFACE_ATTR_RA_DEFAULT, 91 IFACE_ATTR_RA_MANAGEMENT, 92 IFACE_ATTR_RA_FLAGS, 93 IFACE_ATTR_RA_SLAAC, 94 IFACE_ATTR_RA_OFFLINK, 95 IFACE_ATTR_RA_PREFERENCE, 96 IFACE_ATTR_RA_ADVROUTER, 97 IFACE_ATTR_RA_MININTERVAL, 98 IFACE_ATTR_RA_MAXINTERVAL, 99 IFACE_ATTR_RA_LIFETIME, 100 IFACE_ATTR_RA_REACHABLETIME, 101 IFACE_ATTR_RA_RETRANSTIME, 102 IFACE_ATTR_RA_HOPLIMIT, 103 IFACE_ATTR_RA_MTU, 104 IFACE_ATTR_RA_DNS, 105 IFACE_ATTR_RA_PREF64, 106 IFACE_ATTR_PD_MANAGER, 107 IFACE_ATTR_PD_CER, 108 IFACE_ATTR_NDPROXY_ROUTING, 109 IFACE_ATTR_NDPROXY_SLAVE, 110 IFACE_ATTR_PREFIX_FILTER, 111 IFACE_ATTR_MAX_PREFERRED_LIFETIME, 112 IFACE_ATTR_MAX_VALID_LIFETIME, 113 IFACE_ATTR_NTP, 114 IFACE_ATTR_MAX 115 }; 116 117 static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { 118 [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING }, 119 [IFACE_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, 120 [IFACE_ATTR_NETWORKID] = { .name = "networkid", .type = BLOBMSG_TYPE_STRING }, 121 [IFACE_ATTR_DYNAMICDHCP] = { .name = "dynamicdhcp", .type = BLOBMSG_TYPE_BOOL }, 122 [IFACE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 123 [IFACE_ATTR_START] = { .name = "start", .type = BLOBMSG_TYPE_INT32 }, 124 [IFACE_ATTR_LIMIT] = { .name = "limit", .type = BLOBMSG_TYPE_INT32 }, 125 [IFACE_ATTR_MASTER] = { .name = "master", .type = BLOBMSG_TYPE_BOOL }, 126 [IFACE_ATTR_UPSTREAM] = { .name = "upstream", .type = BLOBMSG_TYPE_ARRAY }, 127 [IFACE_ATTR_RA] = { .name = "ra", .type = BLOBMSG_TYPE_STRING }, 128 [IFACE_ATTR_DHCPV4] = { .name = "dhcpv4", .type = BLOBMSG_TYPE_STRING }, 129 [IFACE_ATTR_DHCPV6] = { .name = "dhcpv6", .type = BLOBMSG_TYPE_STRING }, 130 [IFACE_ATTR_NDP] = { .name = "ndp", .type = BLOBMSG_TYPE_STRING }, 131 [IFACE_ATTR_ROUTER] = { .name = "router", .type = BLOBMSG_TYPE_ARRAY }, 132 [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY }, 133 [IFACE_ATTR_DNR] = { .name = "dnr", .type = BLOBMSG_TYPE_ARRAY }, 134 [IFACE_ATTR_DNS_SERVICE] = { .name = "dns_service", .type = BLOBMSG_TYPE_BOOL }, 135 [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY }, 136 [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING }, 137 [IFACE_ATTR_DHCPV4_FORCERECONF] = { .name = "dhcpv4_forcereconf", .type = BLOBMSG_TYPE_BOOL }, 138 [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING }, 139 [IFACE_ATTR_DHCPV6_ASSIGNALL] = { .name ="dhcpv6_assignall", .type = BLOBMSG_TYPE_BOOL }, 140 [IFACE_ATTR_DHCPV6_PD] = { .name = "dhcpv6_pd", .type = BLOBMSG_TYPE_BOOL }, 141 [IFACE_ATTR_DHCPV6_PD_MIN_LEN] = { .name = "dhcpv6_pd_min_len", .type = BLOBMSG_TYPE_INT32 }, 142 [IFACE_ATTR_DHCPV6_NA] = { .name = "dhcpv6_na", .type = BLOBMSG_TYPE_BOOL }, 143 [IFACE_ATTR_DHCPV6_HOSTID_LEN] = { .name = "dhcpv6_hostidlength", .type = BLOBMSG_TYPE_INT32 }, 144 [IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = BLOBMSG_TYPE_STRING }, 145 [IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = BLOBMSG_TYPE_STRING }, 146 [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 }, 147 [IFACE_ATTR_RA_MANAGEMENT] = { .name = "ra_management", .type = BLOBMSG_TYPE_INT32 }, 148 [IFACE_ATTR_RA_FLAGS] = { .name = "ra_flags", . type = BLOBMSG_TYPE_ARRAY }, 149 [IFACE_ATTR_RA_SLAAC] = { .name = "ra_slaac", .type = BLOBMSG_TYPE_BOOL }, 150 [IFACE_ATTR_RA_OFFLINK] = { .name = "ra_offlink", .type = BLOBMSG_TYPE_BOOL }, 151 [IFACE_ATTR_RA_PREFERENCE] = { .name = "ra_preference", .type = BLOBMSG_TYPE_STRING }, 152 [IFACE_ATTR_RA_ADVROUTER] = { .name = "ra_advrouter", .type = BLOBMSG_TYPE_BOOL }, 153 [IFACE_ATTR_RA_MININTERVAL] = { .name = "ra_mininterval", .type = BLOBMSG_TYPE_INT32 }, 154 [IFACE_ATTR_RA_MAXINTERVAL] = { .name = "ra_maxinterval", .type = BLOBMSG_TYPE_INT32 }, 155 [IFACE_ATTR_RA_LIFETIME] = { .name = "ra_lifetime", .type = BLOBMSG_TYPE_INT32 }, 156 [IFACE_ATTR_RA_REACHABLETIME] = { .name = "ra_reachabletime", .type = BLOBMSG_TYPE_INT32 }, 157 [IFACE_ATTR_RA_RETRANSTIME] = { .name = "ra_retranstime", .type = BLOBMSG_TYPE_INT32 }, 158 [IFACE_ATTR_RA_HOPLIMIT] = { .name = "ra_hoplimit", .type = BLOBMSG_TYPE_INT32 }, 159 [IFACE_ATTR_RA_MTU] = { .name = "ra_mtu", .type = BLOBMSG_TYPE_INT32 }, 160 [IFACE_ATTR_RA_DNS] = { .name = "ra_dns", .type = BLOBMSG_TYPE_BOOL }, 161 [IFACE_ATTR_RA_PREF64] = { .name = "ra_pref64", .type = BLOBMSG_TYPE_STRING }, 162 [IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = BLOBMSG_TYPE_BOOL }, 163 [IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = BLOBMSG_TYPE_BOOL }, 164 [IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = BLOBMSG_TYPE_STRING }, 165 [IFACE_ATTR_MAX_PREFERRED_LIFETIME] = { .name = "max_preferred_lifetime", .type = BLOBMSG_TYPE_STRING }, 166 [IFACE_ATTR_MAX_VALID_LIFETIME] = { .name = "max_valid_lifetime", .type = BLOBMSG_TYPE_STRING }, 167 [IFACE_ATTR_NTP] = { .name = "ntp", .type = BLOBMSG_TYPE_ARRAY }, 168 }; 169 170 static const struct uci_blob_param_info iface_attr_info[IFACE_ATTR_MAX] = { 171 [IFACE_ATTR_UPSTREAM] = { .type = BLOBMSG_TYPE_STRING }, 172 [IFACE_ATTR_DNS] = { .type = BLOBMSG_TYPE_STRING }, 173 [IFACE_ATTR_DOMAIN] = { .type = BLOBMSG_TYPE_STRING }, 174 }; 175 176 const struct uci_blob_param_list interface_attr_list = { 177 .n_params = IFACE_ATTR_MAX, 178 .params = iface_attrs, 179 .info = iface_attr_info, 180 }; 181 182 const struct blobmsg_policy lease_attrs[LEASE_ATTR_MAX] = { 183 [LEASE_ATTR_IP] = { .name = "ip", .type = BLOBMSG_TYPE_STRING }, 184 [LEASE_ATTR_MAC] = { .name = "mac", .type = BLOBMSG_TYPE_ARRAY }, 185 [LEASE_ATTR_DUID] = { .name = "duid", .type = BLOBMSG_TYPE_STRING }, 186 [LEASE_ATTR_HOSTID] = { .name = "hostid", .type = BLOBMSG_TYPE_STRING }, 187 [LEASE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 188 [LEASE_ATTR_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 189 }; 190 191 const struct uci_blob_param_list lease_attr_list = { 192 .n_params = LEASE_ATTR_MAX, 193 .params = lease_attrs, 194 }; 195 196 enum { 197 ODHCPD_ATTR_LEGACY, 198 ODHCPD_ATTR_MAINDHCP, 199 ODHCPD_ATTR_LEASEFILE, 200 ODHCPD_ATTR_LEASETRIGGER, 201 ODHCPD_ATTR_LOGLEVEL, 202 ODHCPD_ATTR_HOSTSFILE, 203 ODHCPD_ATTR_MAX 204 }; 205 206 static const struct blobmsg_policy odhcpd_attrs[ODHCPD_ATTR_MAX] = { 207 [ODHCPD_ATTR_LEGACY] = { .name = "legacy", .type = BLOBMSG_TYPE_BOOL }, 208 [ODHCPD_ATTR_MAINDHCP] = { .name = "maindhcp", .type = BLOBMSG_TYPE_BOOL }, 209 [ODHCPD_ATTR_LEASEFILE] = { .name = "leasefile", .type = BLOBMSG_TYPE_STRING }, 210 [ODHCPD_ATTR_LEASETRIGGER] = { .name = "leasetrigger", .type = BLOBMSG_TYPE_STRING }, 211 [ODHCPD_ATTR_LOGLEVEL] = { .name = "loglevel", .type = BLOBMSG_TYPE_INT32 }, 212 [ODHCPD_ATTR_HOSTSFILE] = { .name = "hostsfile", .type = BLOBMSG_TYPE_STRING }, 213 }; 214 215 const struct uci_blob_param_list odhcpd_attr_list = { 216 .n_params = ODHCPD_ATTR_MAX, 217 .params = odhcpd_attrs, 218 }; 219 220 static const struct { const char *name; uint8_t flag; } ra_flags[] = { 221 { .name = "managed-config", .flag = ND_RA_FLAG_MANAGED }, 222 { .name = "other-config", .flag = ND_RA_FLAG_OTHER }, 223 { .name = "home-agent", .flag = ND_RA_FLAG_HOME_AGENT }, 224 { .name = "none", . flag = 0 }, 225 { .name = NULL, }, 226 }; 227 228 // https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml 229 enum svc_param_keys { 230 DNR_SVC_MANDATORY, 231 DNR_SVC_ALPN, 232 DNR_SVC_NO_DEFAULT_ALPN, 233 DNR_SVC_PORT, 234 DNR_SVC_IPV4HINT, 235 DNR_SVC_ECH, 236 DNR_SVC_IPV6HINT, 237 DNR_SVC_DOHPATH, 238 DNR_SVC_OHTTP, 239 DNR_SVC_MAX, 240 }; 241 242 static const char *svc_param_key_names[DNR_SVC_MAX] = { 243 [DNR_SVC_MANDATORY] = "mandatory", 244 [DNR_SVC_ALPN] = "alpn", 245 [DNR_SVC_NO_DEFAULT_ALPN] = "no-default-alpn", 246 [DNR_SVC_PORT] = "port", 247 [DNR_SVC_IPV4HINT] = "ipv4hint", 248 [DNR_SVC_ECH] = "ech", 249 [DNR_SVC_IPV6HINT] = "ipv6hint", 250 [DNR_SVC_DOHPATH] = "dohpath", 251 [DNR_SVC_OHTTP] = "ohttp", 252 }; 253 254 static void set_interface_defaults(struct interface *iface) 255 { 256 iface->ignore = true; 257 iface->dhcpv4 = MODE_DISABLED; 258 iface->dhcpv6 = MODE_DISABLED; 259 iface->ra = MODE_DISABLED; 260 iface->ndp = MODE_DISABLED; 261 iface->learn_routes = 1; 262 iface->dhcp_leasetime = 43200; 263 iface->max_preferred_lifetime = ND_PREFERRED_LIMIT; 264 iface->max_valid_lifetime = ND_VALID_LIMIT; 265 iface->dhcpv4_start.s_addr = htonl(START_DEFAULT); 266 iface->dhcpv4_end.s_addr = htonl(START_DEFAULT + LIMIT_DEFAULT - 1); 267 iface->dhcpv6_assignall = true; 268 iface->dhcpv6_pd = true; 269 iface->dhcpv6_pd_min_len = 0; 270 iface->dhcpv6_na = true; 271 iface->dhcpv6_hostid_len = HOSTID_LEN_DEFAULT; 272 iface->dns_service = true; 273 iface->ra_flags = ND_RA_FLAG_OTHER; 274 iface->ra_slaac = true; 275 iface->ra_maxinterval = 600; 276 iface->ra_mininterval = iface->ra_maxinterval/3; 277 iface->ra_lifetime = -1; 278 iface->ra_dns = true; 279 } 280 281 static void clean_interface(struct interface *iface) 282 { 283 free(iface->dns); 284 free(iface->search); 285 free(iface->upstream); 286 free(iface->dhcpv4_router); 287 free(iface->dhcpv4_dns); 288 free(iface->dhcpv6_raw); 289 free(iface->filter_class); 290 free(iface->dhcpv4_ntp); 291 free(iface->dhcpv6_ntp); 292 free(iface->dhcpv6_sntp); 293 for (unsigned i = 0; i < iface->dnr_cnt; i++) { 294 free(iface->dnr[i].adn); 295 free(iface->dnr[i].addr4); 296 free(iface->dnr[i].addr6); 297 free(iface->dnr[i].svc); 298 } 299 free(iface->dnr); 300 memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra)); 301 set_interface_defaults(iface); 302 } 303 304 static void close_interface(struct interface *iface) 305 { 306 avl_delete(&interfaces, &iface->avl); 307 308 router_setup_interface(iface, false); 309 dhcpv6_setup_interface(iface, false); 310 ndp_setup_interface(iface, false); 311 #ifdef DHCPV4_SUPPORT 312 dhcpv4_setup_interface(iface, false); 313 #endif 314 315 /* make sure timer is not on the timeouts list before freeing */ 316 uloop_timeout_cancel(&iface->timer_rs); 317 318 clean_interface(iface); 319 free(iface->addr4); 320 free(iface->addr6); 321 free(iface->invalid_addr6); 322 free(iface->ifname); 323 free(iface); 324 } 325 326 static int parse_mode(const char *mode) 327 { 328 if (!strcmp(mode, "disabled")) 329 return MODE_DISABLED; 330 else if (!strcmp(mode, "server")) 331 return MODE_SERVER; 332 else if (!strcmp(mode, "relay")) 333 return MODE_RELAY; 334 else if (!strcmp(mode, "hybrid")) 335 return MODE_HYBRID; 336 else 337 return -1; 338 } 339 340 static int parse_ra_flags(uint8_t *flags, struct blob_attr *attr) 341 { 342 struct blob_attr *cur; 343 unsigned rem; 344 345 blobmsg_for_each_attr(cur, attr, rem) { 346 int i; 347 348 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 349 continue; 350 351 if (!blobmsg_check_attr(cur, false)) 352 continue; 353 354 for (i = 0; ra_flags[i].name; i++) { 355 if (!strcmp(ra_flags[i].name, blobmsg_get_string(cur))) { 356 *flags |= ra_flags[i].flag; 357 break; 358 } 359 } 360 361 if (!ra_flags[i].name) 362 return -1; 363 } 364 365 return 0; 366 } 367 368 static void set_config(struct uci_section *s) 369 { 370 struct blob_attr *tb[ODHCPD_ATTR_MAX], *c; 371 372 blob_buf_init(&b, 0); 373 uci_to_blob(&b, s, &odhcpd_attr_list); 374 blobmsg_parse(odhcpd_attrs, ODHCPD_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head)); 375 376 if ((c = tb[ODHCPD_ATTR_LEGACY])) 377 config.legacy = blobmsg_get_bool(c); 378 379 if ((c = tb[ODHCPD_ATTR_MAINDHCP])) 380 config.main_dhcpv4 = blobmsg_get_bool(c); 381 382 if ((c = tb[ODHCPD_ATTR_LEASEFILE])) { 383 free(config.dhcp_statefile); 384 config.dhcp_statefile = strdup(blobmsg_get_string(c)); 385 } 386 387 if ((c = tb[ODHCPD_ATTR_HOSTSFILE])) { 388 free(config.dhcp_hostsfile); 389 config.dhcp_hostsfile = strdup(blobmsg_get_string(c)); 390 } 391 392 if ((c = tb[ODHCPD_ATTR_LEASETRIGGER])) { 393 free(config.dhcp_cb); 394 config.dhcp_cb = strdup(blobmsg_get_string(c)); 395 } 396 397 if ((c = tb[ODHCPD_ATTR_LOGLEVEL])) { 398 int log_level = (blobmsg_get_u32(c) & LOG_PRIMASK); 399 400 if (config.log_level != log_level) { 401 config.log_level = log_level; 402 setlogmask(LOG_UPTO(config.log_level)); 403 } 404 } 405 } 406 407 static double parse_leasetime(struct blob_attr *c) { 408 char *val = blobmsg_get_string(c), *endptr = NULL; 409 double time = strcmp(val, "infinite") ? strtod(val, &endptr) : UINT32_MAX; 410 411 if (time && endptr && endptr[0]) { 412 if (endptr[0] == 's') 413 time *= 1; 414 else if (endptr[0] == 'm') 415 time *= 60; 416 else if (endptr[0] == 'h') 417 time *= 3600; 418 else if (endptr[0] == 'd') 419 time *= 24 * 3600; 420 else if (endptr[0] == 'w') 421 time *= 7 * 24 * 3600; 422 else 423 goto err; 424 } 425 426 if (time < 60) 427 time = 60; 428 429 return time; 430 431 err: 432 return -1; 433 } 434 435 static void free_lease(struct lease *l) 436 { 437 if (!l) 438 return; 439 440 free(l->hostname); 441 free(l); 442 } 443 444 int set_lease_from_blobmsg(struct blob_attr *ba) 445 { 446 struct blob_attr *tb[LEASE_ATTR_MAX], *c; 447 struct lease *l = NULL; 448 int mac_count = 0; 449 struct ether_addr *macs; 450 size_t duidlen = 0; 451 uint8_t *duid; 452 453 blobmsg_parse(lease_attrs, LEASE_ATTR_MAX, tb, blob_data(ba), blob_len(ba)); 454 455 if ((c = tb[LEASE_ATTR_MAC])) { 456 mac_count = blobmsg_check_array_len(c, BLOBMSG_TYPE_STRING, blob_raw_len(c)); 457 if (mac_count < 0) 458 goto err; 459 } 460 461 if ((c = tb[LEASE_ATTR_DUID])) 462 duidlen = (blobmsg_data_len(c) - 1) / 2; 463 464 l = calloc_a(sizeof(*l), 465 &macs, mac_count * sizeof(*macs), 466 &duid, duidlen); 467 if (!l) 468 goto err; 469 470 if ((c = tb[LEASE_ATTR_MAC])) { 471 struct blob_attr *cur; 472 size_t rem; 473 int i = 0; 474 475 l->mac_count = mac_count; 476 l->macs = macs; 477 478 blobmsg_for_each_attr(cur, c, rem) 479 if (!ether_aton_r(blobmsg_get_string(cur), &l->macs[i++])) 480 goto err; 481 } 482 483 if ((c = tb[LEASE_ATTR_DUID])) { 484 ssize_t len; 485 486 l->duid = duid; 487 len = odhcpd_unhexlify(l->duid, duidlen, blobmsg_get_string(c)); 488 489 if (len < 0) 490 goto err; 491 492 l->duid_len = len; 493 } 494 495 if ((c = tb[LEASE_ATTR_NAME])) { 496 l->hostname = strdup(blobmsg_get_string(c)); 497 if (!l->hostname || !odhcpd_valid_hostname(l->hostname)) 498 goto err; 499 } 500 501 if ((c = tb[LEASE_ATTR_IP])) 502 if (inet_pton(AF_INET, blobmsg_get_string(c), &l->ipaddr) < 0) 503 goto err; 504 505 if ((c = tb[LEASE_ATTR_HOSTID])) { 506 errno = 0; 507 l->hostid = strtoull(blobmsg_get_string(c), NULL, 16); 508 if (errno) 509 goto err; 510 } else { 511 uint32_t i4a = ntohl(l->ipaddr) & 0xff; 512 l->hostid = ((i4a / 100) << 8) | (((i4a % 100) / 10) << 4) | (i4a % 10); 513 } 514 515 if ((c = tb[LEASE_ATTR_LEASETIME])) { 516 double time = parse_leasetime(c); 517 if (time < 0) 518 goto err; 519 520 l->leasetime = time; 521 } 522 523 INIT_LIST_HEAD(&l->assignments); 524 vlist_add(&leases, &l->node, l); 525 return 0; 526 527 err: 528 free_lease(l); 529 return -1; 530 } 531 532 static int set_lease_from_uci(struct uci_section *s) 533 { 534 blob_buf_init(&b, 0); 535 uci_to_blob(&b, s, &lease_attr_list); 536 537 return set_lease_from_blobmsg(b.head); 538 } 539 540 /* Parse NTP Options for DHCPv6 Address */ 541 static int parse_ntp_options(uint16_t *dhcpv6_ntp_len, struct in6_addr addr6, uint8_t **dhcpv6_ntp) 542 { 543 uint16_t sub_opt = 0, sub_len = htons(IPV6_ADDR_LEN); 544 uint16_t ntp_len = IPV6_ADDR_LEN + 4; 545 uint8_t *ntp = *dhcpv6_ntp; 546 size_t pos = *dhcpv6_ntp_len; 547 548 ntp = realloc(ntp, pos + ntp_len); 549 if (!ntp) 550 return -1; 551 552 *dhcpv6_ntp = ntp; 553 554 if (IN6_IS_ADDR_MULTICAST(&addr6)) 555 sub_opt = htons(NTP_SUBOPTION_MC_ADDR); 556 else 557 sub_opt = htons(NTP_SUBOPTION_SRV_ADDR); 558 559 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 560 pos += sizeof(sub_opt); 561 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 562 pos += sizeof(sub_len); 563 memcpy(ntp + pos, &addr6, IPV6_ADDR_LEN); 564 565 *dhcpv6_ntp_len += ntp_len; 566 567 return 0; 568 } 569 570 /* Parse NTP Options for FQDN */ 571 static int parse_ntp_fqdn(uint16_t *dhcpv6_ntp_len, char *fqdn, uint8_t **dhcpv6_ntp) 572 { 573 size_t fqdn_len = strlen(fqdn); 574 uint16_t sub_opt = 0, sub_len = 0, ntp_len = 0; 575 uint8_t *ntp = *dhcpv6_ntp; 576 size_t pos = *dhcpv6_ntp_len; 577 uint8_t buf[256] = {0}; 578 579 if (fqdn_len > 0 && fqdn[fqdn_len - 1] == '.') 580 fqdn[fqdn_len - 1] = 0; 581 582 int len = dn_comp(fqdn, buf, sizeof(buf), NULL, NULL); 583 if (len <= 0) 584 return -1; 585 586 ntp_len = len + 4; 587 588 ntp = realloc(ntp, pos + ntp_len); 589 if (!ntp) 590 return -1; 591 592 *dhcpv6_ntp = ntp; 593 594 sub_opt = htons(NTP_SUBOPTION_SRV_FQDN); 595 sub_len = htons(len); 596 597 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 598 pos += sizeof(sub_opt); 599 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 600 pos += sizeof(sub_len); 601 memcpy(ntp + pos, buf, len); 602 603 *dhcpv6_ntp_len += ntp_len; 604 605 return 0; 606 } 607 608 /* Parse DNR Options */ 609 static int parse_dnr_str(char *str, struct interface *iface) 610 { 611 struct dnr_options dnr = {0}; 612 size_t adn_len; 613 uint8_t adn_buf[256] = {0}; 614 char *saveptr1, *saveptr2; 615 616 char *priority; 617 priority = strtok_r(str, " \f\n\r\t\v", &saveptr1); 618 if (!priority) { 619 goto err; 620 } else if (sscanf(priority, "%" SCNu16, &dnr.priority) != 1) { 621 syslog(LOG_ERR, "Unable to parse priority '%s'", priority); 622 goto err; 623 } else if (dnr.priority == 0) { 624 syslog(LOG_ERR, "Invalid priority '%s'", priority); 625 goto err; 626 } 627 628 char *adn; 629 adn = strtok_r(NULL, " \f\n\r\t\v", &saveptr1); 630 if (!adn) 631 goto err; 632 633 adn_len = strlen(adn); 634 if (adn_len > 0 && adn[adn_len - 1] == '.') 635 adn[adn_len - 1] = '\0'; 636 637 if (adn_len >= sizeof(adn_buf)) { 638 syslog(LOG_ERR, "Hostname '%s' too long", adn); 639 goto err; 640 } 641 642 adn_len = dn_comp(adn, adn_buf, sizeof(adn_buf), NULL, NULL); 643 if (adn_len <= 0) { 644 syslog(LOG_ERR, "Unable to parse hostname '%s'", adn); 645 goto err; 646 } 647 648 dnr.adn = malloc(adn_len); 649 if (!dnr.adn) 650 goto err; 651 memcpy(dnr.adn, adn_buf, adn_len); 652 dnr.adn_len = adn_len; 653 654 char *addrs; 655 addrs = strtok_r(NULL, " \f\n\r\t\v", &saveptr1); 656 if (!addrs) 657 // ADN-Only mode 658 goto done; 659 660 for (char *addr = strtok_r(addrs, ",", &saveptr2); addr; addr = strtok_r(NULL, ",", &saveptr2)) { 661 struct in6_addr addr6, *tmp6; 662 struct in_addr addr4, *tmp4; 663 size_t new_sz; 664 665 if (inet_pton(AF_INET6, addr, &addr6) == 1) { 666 new_sz = (dnr.addr6_cnt + 1) * sizeof(*dnr.addr6); 667 if (new_sz > UINT16_MAX) 668 continue; 669 tmp6 = realloc(dnr.addr6, new_sz); 670 if (!tmp6) 671 goto err; 672 dnr.addr6 = tmp6; 673 memcpy(&dnr.addr6[dnr.addr6_cnt], &addr6, sizeof(*dnr.addr6)); 674 dnr.addr6_cnt++; 675 676 } else if (inet_pton(AF_INET, addr, &addr4) == 1) { 677 new_sz = (dnr.addr4_cnt + 1) * sizeof(*dnr.addr4); 678 if (new_sz > UINT8_MAX) 679 continue; 680 tmp4 = realloc(dnr.addr4, new_sz); 681 if (!tmp4) 682 goto err; 683 dnr.addr4 = tmp4; 684 memcpy(&dnr.addr4[dnr.addr4_cnt], &addr4, sizeof(*dnr.addr4)); 685 dnr.addr4_cnt++; 686 687 } else { 688 syslog(LOG_ERR, "Unable to parse IP address '%s'", addr); 689 goto err; 690 } 691 } 692 693 char *svc_vals[DNR_SVC_MAX] = { NULL, }; 694 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)) { 695 uint16_t svc_id; 696 char *svc_key, *svc_val; 697 698 svc_key = strtok_r(svc_tok, "=", &saveptr2); 699 svc_val = strtok_r(NULL, "=", &saveptr2); 700 701 if (!strcmp(svc_key, "_lifetime")) { 702 uint32_t lifetime; 703 704 if (!svc_val || sscanf(svc_val, "%" SCNu32, &lifetime) != 1) { 705 syslog(LOG_ERR, "Invalid value '%s' for _lifetime", svc_val ? svc_val : ""); 706 goto err; 707 } 708 709 dnr.lifetime = lifetime; 710 dnr.lifetime_set = true; 711 continue; 712 } 713 714 for (svc_id = 0; svc_id < DNR_SVC_MAX; svc_id++) 715 if (!strcmp(svc_key, svc_param_key_names[svc_id])) 716 break; 717 718 if (svc_id >= DNR_SVC_MAX) { 719 syslog(LOG_ERR, "Invalid SvcParam '%s'", svc_key); 720 goto err; 721 } 722 723 svc_vals[svc_id] = svc_val ? svc_val : ""; 724 } 725 726 /* SvcParamKeys must be in increasing order, RFC9460 §2.2 */ 727 for (uint16_t svc_key = 0; svc_key < DNR_SVC_MAX; svc_key++) { 728 uint16_t svc_key_be = ntohs(svc_key); 729 uint16_t svc_val_len, svc_val_len_be; 730 char *svc_val_str = svc_vals[svc_key]; 731 uint8_t *tmp; 732 733 if (!svc_val_str) 734 continue; 735 736 switch (svc_key) { 737 case DNR_SVC_MANDATORY: 738 uint16_t mkeys[DNR_SVC_MAX]; 739 740 svc_val_len = 0; 741 for (char *mkey_str = strtok_r(svc_val_str, ",", &saveptr2); mkey_str; mkey_str = strtok_r(NULL, ",", &saveptr2)) { 742 uint16_t mkey; 743 744 for (mkey = 0; mkey < DNR_SVC_MAX; mkey++) 745 if (!strcmp(mkey_str, svc_param_key_names[mkey])) 746 break; 747 748 if (mkey >= DNR_SVC_MAX || !svc_vals[mkey]) { 749 syslog(LOG_ERR, "Invalid value '%s' for SvcParam 'mandatory'", mkey_str); 750 goto err; 751 } 752 753 mkeys[svc_val_len++] = ntohs(mkey); 754 } 755 756 svc_val_len *= sizeof(uint16_t); 757 svc_val_len_be = ntohs(svc_val_len); 758 759 tmp = realloc(dnr.svc, dnr.svc_len + 4 + svc_val_len); 760 if (!tmp) 761 goto err; 762 763 dnr.svc = tmp; 764 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 765 memcpy(dnr.svc + dnr.svc_len + 2, &svc_val_len_be, sizeof(svc_val_len_be)); 766 memcpy(dnr.svc + dnr.svc_len + 4, mkeys, svc_val_len); 767 dnr.svc_len += 4 + svc_val_len; 768 break; 769 770 case DNR_SVC_ALPN: 771 size_t len_off; 772 773 tmp = realloc(dnr.svc, dnr.svc_len + 4); 774 if (!tmp) 775 goto err; 776 777 dnr.svc = tmp; 778 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 779 /* the length is not known yet */ 780 len_off = dnr.svc_len + sizeof(svc_key_be); 781 dnr.svc_len += 4; 782 783 svc_val_len = 0; 784 for (char *alpn_id_str = strtok_r(svc_val_str, ",", &saveptr2); alpn_id_str; alpn_id_str = strtok_r(NULL, ",", &saveptr2)) { 785 size_t alpn_id_len; 786 787 alpn_id_len = strlen(alpn_id_str); 788 if (alpn_id_len > UINT8_MAX) { 789 syslog(LOG_ERR, "Invalid value '%s' for SvcParam 'alpn'", alpn_id_str); 790 goto err; 791 } 792 793 tmp = realloc(dnr.svc, dnr.svc_len + 1 + alpn_id_len); 794 if (!tmp) 795 goto err; 796 dnr.svc = tmp; 797 798 dnr.svc[dnr.svc_len] = alpn_id_len; 799 memcpy(dnr.svc + dnr.svc_len + 1, alpn_id_str, alpn_id_len); 800 dnr.svc_len += 1 + alpn_id_len; 801 svc_val_len += 1 + alpn_id_len; 802 } 803 804 svc_val_len_be = ntohs(svc_val_len); 805 memcpy(dnr.svc + len_off, &svc_val_len_be, sizeof(svc_val_len_be)); 806 break; 807 808 case DNR_SVC_PORT: 809 uint16_t port; 810 811 if (sscanf(svc_val_str, "%" SCNu16, &port) != 1) { 812 syslog(LOG_ERR, "Invalid value '%s' for SvcParam 'port'", svc_val_str); 813 goto err; 814 } 815 816 port = ntohs(port); 817 svc_val_len_be = ntohs(2); 818 819 tmp = realloc(dnr.svc, dnr.svc_len + 6); 820 if (!tmp) 821 goto err; 822 823 dnr.svc = tmp; 824 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 825 memcpy(dnr.svc + dnr.svc_len + 2, &svc_val_len_be, sizeof(svc_val_len_be)); 826 memcpy(dnr.svc + dnr.svc_len + 4, &port, sizeof(port)); 827 dnr.svc_len += 6; 828 break; 829 830 case DNR_SVC_NO_DEFAULT_ALPN: 831 /* fall through */ 832 833 case DNR_SVC_OHTTP: 834 if (strlen(svc_val_str) > 0) { 835 syslog(LOG_ERR, "Invalid value '%s' for SvcParam 'port'", svc_val_str); 836 goto err; 837 } 838 /* fall through */ 839 840 case DNR_SVC_DOHPATH: 841 /* plain string */ 842 svc_val_len = strlen(svc_val_str); 843 svc_val_len_be = ntohs(svc_val_len); 844 tmp = realloc(dnr.svc, dnr.svc_len + 4 + svc_val_len); 845 if (!tmp) 846 goto err; 847 848 dnr.svc = tmp; 849 memcpy(dnr.svc + dnr.svc_len, &svc_key_be, sizeof(svc_key_be)); 850 dnr.svc_len += sizeof(svc_key_be); 851 memcpy(dnr.svc + dnr.svc_len, &svc_val_len_be, sizeof(svc_val_len_be)); 852 dnr.svc_len += sizeof(svc_val_len_be); 853 memcpy(dnr.svc + dnr.svc_len, svc_val_str, svc_val_len); 854 dnr.svc_len += svc_val_len; 855 break; 856 857 case DNR_SVC_ECH: 858 syslog(LOG_ERR, "SvcParam 'ech' is not implemented"); 859 goto err; 860 861 case DNR_SVC_IPV4HINT: 862 /* fall through */ 863 864 case DNR_SVC_IPV6HINT: 865 syslog(LOG_ERR, "SvcParam '%s' is not allowed", svc_param_key_names[svc_key]); 866 goto err; 867 } 868 } 869 870 done: 871 struct dnr_options *tmp; 872 tmp = realloc(iface->dnr, (iface->dnr_cnt + 1) * sizeof(dnr)); 873 if (!tmp) 874 goto err; 875 876 iface->dnr = tmp; 877 memcpy(iface->dnr + iface->dnr_cnt, &dnr, sizeof(dnr)); 878 iface->dnr_cnt++; 879 return 0; 880 881 err: 882 free(dnr.adn); 883 free(dnr.addr4); 884 free(dnr.addr6); 885 free(dnr.svc); 886 return -1; 887 } 888 889 int config_parse_interface(void *data, size_t len, const char *name, bool overwrite) 890 { 891 struct odhcpd_ipaddr *addrs = NULL; 892 struct interface *iface; 893 struct blob_attr *tb[IFACE_ATTR_MAX], *c; 894 ssize_t addrs_len; 895 bool get_addrs = false; 896 int mode; 897 const char *ifname = NULL; 898 899 blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, data, len); 900 901 if (tb[IFACE_ATTR_INTERFACE]) 902 name = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]); 903 904 if (!name) 905 return -1; 906 907 iface = avl_find_element(&interfaces, name, iface, avl); 908 if (!iface) { 909 char *new_name; 910 911 iface = calloc_a(sizeof(*iface), &new_name, strlen(name) + 1); 912 if (!iface) 913 return -1; 914 915 iface->name = strcpy(new_name, name); 916 iface->avl.key = iface->name; 917 iface->router_event.uloop.fd = -1; 918 iface->dhcpv6_event.uloop.fd = -1; 919 iface->ndp_event.uloop.fd = -1; 920 iface->ndp_ping_fd = -1; 921 iface->dhcpv4_event.uloop.fd = -1; 922 INIT_LIST_HEAD(&iface->ia_assignments); 923 INIT_LIST_HEAD(&iface->dhcpv4_assignments); 924 INIT_LIST_HEAD(&iface->dhcpv4_fr_ips); 925 926 set_interface_defaults(iface); 927 928 avl_insert(&interfaces, &iface->avl); 929 get_addrs = overwrite = true; 930 } 931 932 if (overwrite) { 933 if ((c = tb[IFACE_ATTR_IFNAME])) 934 ifname = blobmsg_get_string(c); 935 else if ((c = tb[IFACE_ATTR_NETWORKID])) 936 ifname = blobmsg_get_string(c); 937 } 938 939 #ifdef WITH_UBUS 940 if (overwrite || !iface->ifname) 941 ifname = ubus_get_ifname(name); 942 #endif 943 944 if (!iface->ifname && !ifname) 945 goto err; 946 947 if (ifname) { 948 free(iface->ifname); 949 iface->ifname = strdup(ifname); 950 951 if (!iface->ifname) 952 goto err; 953 954 if (!iface->ifindex && 955 (iface->ifindex = if_nametoindex(iface->ifname)) <= 0) 956 goto err; 957 958 if ((iface->ifflags = odhcpd_get_flags(iface)) < 0) 959 goto err; 960 } 961 962 if (get_addrs) { 963 addrs_len = netlink_get_interface_addrs(iface->ifindex, 964 true, &iface->addr6); 965 966 if (addrs_len > 0) 967 iface->addr6_len = addrs_len; 968 969 addrs_len = netlink_get_interface_addrs(iface->ifindex, 970 false, &iface->addr4); 971 if (addrs_len > 0) 972 iface->addr4_len = addrs_len; 973 } 974 975 addrs_len = netlink_get_interface_linklocal(iface->ifindex, &addrs); 976 if (addrs_len > 0) { 977 for (ssize_t i = 0; i < addrs_len; i++) { 978 if (!addrs[i].tentative) { 979 iface->have_link_local = true; 980 break; 981 } 982 } 983 free(addrs); 984 } 985 986 iface->inuse = true; 987 988 if ((c = tb[IFACE_ATTR_DYNAMICDHCP])) 989 iface->no_dynamic_dhcp = !blobmsg_get_bool(c); 990 991 if ((c = tb[IFACE_ATTR_LEASETIME])) { 992 double time = parse_leasetime(c); 993 994 if (time >= 0) 995 iface->dhcp_leasetime = time; 996 else 997 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 998 iface_attrs[IFACE_ATTR_LEASETIME].name, iface->name); 999 1000 } 1001 1002 if ((c = tb[IFACE_ATTR_MAX_PREFERRED_LIFETIME])) { 1003 double time = parse_leasetime(c); 1004 1005 if (time >= 0) { 1006 iface->max_preferred_lifetime = time; 1007 } else { 1008 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1009 iface_attrs[IFACE_ATTR_MAX_PREFERRED_LIFETIME].name, iface->name); 1010 } 1011 } 1012 1013 if ((c = tb[IFACE_ATTR_MAX_VALID_LIFETIME])) { 1014 double time = parse_leasetime(c); 1015 1016 if (time >= 0) { 1017 iface->max_valid_lifetime = time; 1018 } else { 1019 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1020 iface_attrs[IFACE_ATTR_MAX_VALID_LIFETIME].name, iface->name); 1021 } 1022 } 1023 1024 if ((c = tb[IFACE_ATTR_START])) { 1025 iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c)); 1026 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) + 1027 LIMIT_DEFAULT - 1); 1028 1029 if (config.main_dhcpv4 && config.legacy) 1030 iface->dhcpv4 = MODE_SERVER; 1031 } 1032 1033 if ((c = tb[IFACE_ATTR_LIMIT])) 1034 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) + 1035 blobmsg_get_u32(c) - 1); 1036 1037 if ((c = tb[IFACE_ATTR_MASTER])) 1038 iface->master = blobmsg_get_bool(c); 1039 1040 if (overwrite && (c = tb[IFACE_ATTR_UPSTREAM])) { 1041 struct blob_attr *cur; 1042 unsigned rem; 1043 1044 blobmsg_for_each_attr(cur, c, rem) { 1045 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1046 continue; 1047 1048 iface->upstream = realloc(iface->upstream, 1049 iface->upstream_len + blobmsg_data_len(cur)); 1050 if (!iface->upstream) 1051 goto err; 1052 1053 memcpy(iface->upstream + iface->upstream_len, blobmsg_get_string(cur), blobmsg_data_len(cur)); 1054 iface->upstream_len += blobmsg_data_len(cur); 1055 } 1056 } 1057 1058 if ((c = tb[IFACE_ATTR_RA])) { 1059 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1060 iface->ra = mode; 1061 1062 if (iface->ra != MODE_DISABLED) 1063 iface->ignore = false; 1064 } else 1065 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 1066 iface_attrs[IFACE_ATTR_RA].name, iface->name); 1067 } 1068 1069 if ((c = tb[IFACE_ATTR_DHCPV4])) { 1070 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1071 if (config.main_dhcpv4) { 1072 iface->dhcpv4 = mode; 1073 1074 if (iface->dhcpv4 != MODE_DISABLED) 1075 iface->ignore = false; 1076 } 1077 } else 1078 syslog(LOG_ERR, "Invalid %s mode configured for interface %s", 1079 iface_attrs[IFACE_ATTR_DHCPV4].name, iface->name); 1080 } 1081 1082 if ((c = tb[IFACE_ATTR_DHCPV6])) { 1083 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1084 iface->dhcpv6 = mode; 1085 1086 if (iface->dhcpv6 != MODE_DISABLED) 1087 iface->ignore = false; 1088 } else 1089 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 1090 iface_attrs[IFACE_ATTR_DHCPV6].name, iface->name); 1091 } 1092 1093 if ((c = tb[IFACE_ATTR_NDP])) { 1094 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 1095 iface->ndp = mode; 1096 1097 if (iface->ndp != MODE_DISABLED) 1098 iface->ignore = false; 1099 } else 1100 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 1101 iface_attrs[IFACE_ATTR_NDP].name, iface->name); 1102 } 1103 1104 if ((c = tb[IFACE_ATTR_ROUTER])) { 1105 struct blob_attr *cur; 1106 unsigned rem; 1107 1108 blobmsg_for_each_attr(cur, c, rem) { 1109 struct in_addr addr4; 1110 1111 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1112 continue; 1113 1114 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 1115 iface->dhcpv4_router = realloc(iface->dhcpv4_router, 1116 (++iface->dhcpv4_router_cnt) * sizeof(*iface->dhcpv4_router)); 1117 if (!iface->dhcpv4_router) 1118 goto err; 1119 1120 iface->dhcpv4_router[iface->dhcpv4_router_cnt - 1] = addr4; 1121 } else 1122 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1123 iface_attrs[IFACE_ATTR_ROUTER].name, iface->name); 1124 } 1125 } 1126 1127 if ((c = tb[IFACE_ATTR_DNS])) { 1128 struct blob_attr *cur; 1129 unsigned rem; 1130 1131 iface->always_rewrite_dns = true; 1132 blobmsg_for_each_attr(cur, c, rem) { 1133 struct in_addr addr4; 1134 struct in6_addr addr6; 1135 1136 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1137 continue; 1138 1139 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 1140 if (addr4.s_addr == INADDR_ANY) { 1141 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1142 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 1143 1144 continue; 1145 } 1146 1147 iface->dhcpv4_dns = realloc(iface->dhcpv4_dns, 1148 (++iface->dhcpv4_dns_cnt) * sizeof(*iface->dhcpv4_dns)); 1149 if (!iface->dhcpv4_dns) 1150 goto err; 1151 1152 iface->dhcpv4_dns[iface->dhcpv4_dns_cnt - 1] = addr4; 1153 } else if (inet_pton(AF_INET6, blobmsg_get_string(cur), &addr6) == 1) { 1154 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { 1155 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1156 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 1157 1158 continue; 1159 } 1160 1161 iface->dns = realloc(iface->dns, 1162 (++iface->dns_cnt) * sizeof(*iface->dns)); 1163 if (!iface->dns) 1164 goto err; 1165 1166 iface->dns[iface->dns_cnt - 1] = addr6; 1167 } else 1168 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1169 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 1170 } 1171 } 1172 1173 if ((c = tb[IFACE_ATTR_DNS_SERVICE])) 1174 iface->dns_service = blobmsg_get_bool(c); 1175 1176 if ((c = tb[IFACE_ATTR_DOMAIN])) { 1177 struct blob_attr *cur; 1178 unsigned rem; 1179 1180 blobmsg_for_each_attr(cur, c, rem) { 1181 uint8_t buf[256]; 1182 char *domain = blobmsg_get_string(cur); 1183 size_t domainlen = strlen(domain); 1184 int len; 1185 1186 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1187 continue; 1188 1189 domain = blobmsg_get_string(cur); 1190 domainlen = strlen(domain); 1191 1192 if (domainlen > 0 && domain[domainlen - 1] == '.') 1193 domain[domainlen - 1] = 0; 1194 1195 len = dn_comp(domain, buf, sizeof(buf), NULL, NULL); 1196 if (len <= 0) { 1197 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1198 iface_attrs[IFACE_ATTR_DOMAIN].name, iface->name); 1199 1200 continue; 1201 } 1202 1203 iface->search = realloc(iface->search, iface->search_len + len); 1204 if (!iface->search) 1205 goto err; 1206 1207 memcpy(&iface->search[iface->search_len], buf, len); 1208 iface->search_len += len; 1209 } 1210 } 1211 1212 if ((c = tb[IFACE_ATTR_FILTER_CLASS])) { 1213 iface->filter_class = realloc(iface->filter_class, blobmsg_data_len(c) + 1); 1214 memcpy(iface->filter_class, blobmsg_get_string(c), blobmsg_data_len(c) + 1); 1215 } 1216 1217 if ((c = tb[IFACE_ATTR_DHCPV4_FORCERECONF])) 1218 iface->dhcpv4_forcereconf = blobmsg_get_bool(c); 1219 1220 if ((c = tb[IFACE_ATTR_DHCPV6_RAW])) { 1221 iface->dhcpv6_raw_len = blobmsg_data_len(c) / 2; 1222 iface->dhcpv6_raw = realloc(iface->dhcpv6_raw, iface->dhcpv6_raw_len); 1223 odhcpd_unhexlify(iface->dhcpv6_raw, iface->dhcpv6_raw_len, blobmsg_get_string(c)); 1224 } 1225 1226 if ((c = tb[IFACE_ATTR_DHCPV6_ASSIGNALL])) 1227 iface->dhcpv6_assignall = blobmsg_get_bool(c); 1228 1229 if ((c = tb[IFACE_ATTR_DHCPV6_PD])) 1230 iface->dhcpv6_pd = blobmsg_get_bool(c); 1231 1232 if ((c = tb[IFACE_ATTR_DHCPV6_PD_MIN_LEN])) { 1233 uint32_t pd_min_len = blobmsg_get_u32(c); 1234 if (pd_min_len != 0 && pd_min_len <= PD_MIN_LEN_MAX) 1235 iface->dhcpv6_pd_min_len = pd_min_len; 1236 else 1237 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1238 iface_attrs[IFACE_ATTR_DHCPV6_PD_MIN_LEN].name, iface->name); 1239 } 1240 1241 if ((c = tb[IFACE_ATTR_DHCPV6_NA])) 1242 iface->dhcpv6_na = blobmsg_get_bool(c); 1243 1244 if ((c = tb[IFACE_ATTR_DHCPV6_HOSTID_LEN])) { 1245 uint32_t hostid_len = blobmsg_get_u32(c); 1246 1247 if (hostid_len >= HOSTID_LEN_MIN && hostid_len <= HOSTID_LEN_MAX) 1248 iface->dhcpv6_hostid_len = hostid_len; 1249 else 1250 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1251 iface_attrs[IFACE_ATTR_DHCPV6_HOSTID_LEN].name, iface->name); 1252 1253 } 1254 1255 if ((c = tb[IFACE_ATTR_RA_DEFAULT])) 1256 iface->default_router = blobmsg_get_u32(c); 1257 1258 /* IFACE_ATTR_RA_MANAGEMENT aka ra_management is deprecated since 2019 */ 1259 if (!tb[IFACE_ATTR_RA_FLAGS] && !tb[IFACE_ATTR_RA_SLAAC] && 1260 (c = tb[IFACE_ATTR_RA_MANAGEMENT])) { 1261 switch (blobmsg_get_u32(c)) { 1262 case 0: 1263 iface->ra_flags = ND_RA_FLAG_OTHER; 1264 iface->ra_slaac = true; 1265 break; 1266 case 1: 1267 iface->ra_flags = ND_RA_FLAG_OTHER|ND_RA_FLAG_MANAGED; 1268 iface->ra_slaac = true; 1269 break; 1270 case 2: 1271 iface->ra_flags = ND_RA_FLAG_OTHER|ND_RA_FLAG_MANAGED; 1272 iface->ra_slaac = false; 1273 break; 1274 default: 1275 break; 1276 } 1277 } 1278 1279 if ((c = tb[IFACE_ATTR_RA_FLAGS])) { 1280 iface->ra_flags = 0; 1281 1282 if (parse_ra_flags(&iface->ra_flags, c) < 0) 1283 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1284 iface_attrs[IFACE_ATTR_RA_FLAGS].name, iface->name); 1285 } 1286 1287 if ((c = tb[IFACE_ATTR_RA_REACHABLETIME])) { 1288 uint32_t ra_reachabletime = blobmsg_get_u32(c); 1289 1290 if (ra_reachabletime <= 3600000) 1291 iface->ra_reachabletime = ra_reachabletime; 1292 else 1293 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1294 iface_attrs[IFACE_ATTR_RA_REACHABLETIME].name, iface->name); 1295 } 1296 1297 if ((c = tb[IFACE_ATTR_RA_RETRANSTIME])) { 1298 uint32_t ra_retranstime = blobmsg_get_u32(c); 1299 1300 if (ra_retranstime <= 60000) 1301 iface->ra_retranstime = ra_retranstime; 1302 else 1303 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1304 iface_attrs[IFACE_ATTR_RA_RETRANSTIME].name, iface->name); 1305 } 1306 1307 if ((c = tb[IFACE_ATTR_RA_HOPLIMIT])) { 1308 uint32_t ra_hoplimit = blobmsg_get_u32(c); 1309 1310 if (ra_hoplimit <= 255) 1311 iface->ra_hoplimit = ra_hoplimit; 1312 else 1313 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1314 iface_attrs[IFACE_ATTR_RA_HOPLIMIT].name, iface->name); 1315 } 1316 1317 if ((c = tb[IFACE_ATTR_RA_MTU])) { 1318 uint32_t ra_mtu = blobmsg_get_u32(c); 1319 1320 if (ra_mtu >= 1280 || ra_mtu <= 65535) 1321 iface->ra_mtu = ra_mtu; 1322 else 1323 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1324 iface_attrs[IFACE_ATTR_RA_MTU].name, iface->name); 1325 } 1326 1327 if ((c = tb[IFACE_ATTR_RA_SLAAC])) 1328 iface->ra_slaac = blobmsg_get_bool(c); 1329 1330 if ((c = tb[IFACE_ATTR_RA_OFFLINK])) 1331 iface->ra_not_onlink = blobmsg_get_bool(c); 1332 1333 if ((c = tb[IFACE_ATTR_RA_ADVROUTER])) 1334 iface->ra_advrouter = blobmsg_get_bool(c); 1335 1336 if ((c = tb[IFACE_ATTR_RA_MININTERVAL])) 1337 iface->ra_mininterval = blobmsg_get_u32(c); 1338 1339 if ((c = tb[IFACE_ATTR_RA_MAXINTERVAL])) 1340 iface->ra_maxinterval = blobmsg_get_u32(c); 1341 1342 if ((c = tb[IFACE_ATTR_RA_LIFETIME])) 1343 iface->ra_lifetime = blobmsg_get_u32(c); 1344 1345 if ((c = tb[IFACE_ATTR_RA_DNS])) 1346 iface->ra_dns = blobmsg_get_bool(c); 1347 1348 if ((c = tb[IFACE_ATTR_DNR])) { 1349 struct blob_attr *cur; 1350 unsigned rem; 1351 1352 blobmsg_for_each_attr(cur, c, rem) { 1353 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1354 continue; 1355 1356 if (parse_dnr_str(blobmsg_get_string(cur), iface)) 1357 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1358 iface_attrs[IFACE_ATTR_DNR].name, iface->name); 1359 } 1360 } 1361 1362 if ((c = tb[IFACE_ATTR_RA_PREF64])) { 1363 struct in6_addr addr; 1364 1365 odhcpd_parse_addr6_prefix(blobmsg_get_string(c), 1366 &addr, &iface->pref64_length); 1367 1368 iface->pref64_prefix[0] = addr.s6_addr32[0]; 1369 switch (iface->pref64_length) { 1370 case 96: 1371 iface->pref64_plc = 0; 1372 iface->pref64_prefix[1] = addr.s6_addr32[1]; 1373 iface->pref64_prefix[2] = addr.s6_addr32[2]; 1374 break; 1375 case 64: 1376 iface->pref64_plc = 1; 1377 iface->pref64_prefix[1] = addr.s6_addr32[1]; 1378 iface->pref64_prefix[2] = 0; 1379 break; 1380 case 56: 1381 iface->pref64_plc = 2; 1382 iface->pref64_prefix[1] = addr.s6_addr32[1] & htonl(0xffffff00); 1383 iface->pref64_prefix[2] = 0; 1384 break; 1385 case 48: 1386 iface->pref64_plc = 3; 1387 iface->pref64_prefix[1] = addr.s6_addr32[1] & htonl(0xffff0000); 1388 iface->pref64_prefix[2] = 0; 1389 break; 1390 case 40: 1391 iface->pref64_plc = 4; 1392 iface->pref64_prefix[1] = addr.s6_addr32[1] & htonl(0xff000000); 1393 iface->pref64_prefix[2] = 0; 1394 break; 1395 case 32: 1396 iface->pref64_plc = 5; 1397 iface->pref64_prefix[1] = 0; 1398 iface->pref64_prefix[2] = 0; 1399 break; 1400 default: 1401 syslog(LOG_WARNING, "Invalid PREF64 prefix size (%d), " 1402 "ignoring ra_pref64 option!", iface->pref64_length); 1403 iface->pref64_length = 0; 1404 } 1405 } 1406 1407 if ((c = tb[IFACE_ATTR_RA_PREFERENCE])) { 1408 const char *prio = blobmsg_get_string(c); 1409 1410 if (!strcmp(prio, "high")) 1411 iface->route_preference = 1; 1412 else if (!strcmp(prio, "low")) 1413 iface->route_preference = -1; 1414 else if (!strcmp(prio, "medium") || !strcmp(prio, "default")) 1415 iface->route_preference = 0; 1416 else 1417 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 1418 iface_attrs[IFACE_ATTR_RA_PREFERENCE].name, iface->name); 1419 } 1420 1421 if ((c = tb[IFACE_ATTR_PD_MANAGER])) 1422 strncpy(iface->dhcpv6_pd_manager, blobmsg_get_string(c), 1423 sizeof(iface->dhcpv6_pd_manager) - 1); 1424 1425 if ((c = tb[IFACE_ATTR_PD_CER]) && 1426 inet_pton(AF_INET6, blobmsg_get_string(c), &iface->dhcpv6_pd_cer) < 1) 1427 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1428 iface_attrs[IFACE_ATTR_PD_CER].name, iface->name); 1429 1430 if ((c = tb[IFACE_ATTR_NDPROXY_ROUTING])) 1431 iface->learn_routes = blobmsg_get_bool(c); 1432 1433 if ((c = tb[IFACE_ATTR_NDPROXY_SLAVE])) 1434 iface->external = blobmsg_get_bool(c); 1435 1436 if ((c = tb[IFACE_ATTR_PREFIX_FILTER])) 1437 odhcpd_parse_addr6_prefix(blobmsg_get_string(c), 1438 &iface->pio_filter_addr, 1439 &iface->pio_filter_length); 1440 1441 if (overwrite && (c = tb[IFACE_ATTR_NTP])) { 1442 struct blob_attr *cur; 1443 unsigned rem; 1444 1445 blobmsg_for_each_attr(cur, c, rem) { 1446 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1447 continue; 1448 1449 char *str = blobmsg_get_string(cur); 1450 struct in_addr addr4; 1451 struct in6_addr addr6; 1452 1453 if (inet_pton(AF_INET, str, &addr4) == 1) { 1454 if (addr4.s_addr == INADDR_ANY) 1455 goto err; 1456 1457 iface->dhcpv4_ntp = realloc(iface->dhcpv4_ntp, 1458 (++iface->dhcpv4_ntp_cnt) * sizeof(*iface->dhcpv4_ntp)); 1459 if (!iface->dhcpv4_ntp) 1460 goto err; 1461 1462 iface->dhcpv4_ntp[iface->dhcpv4_ntp_cnt - 1] = addr4; 1463 } else if (inet_pton(AF_INET6, str, &addr6) == 1) { 1464 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) 1465 goto err; 1466 1467 iface->dhcpv6_sntp = realloc(iface->dhcpv6_sntp, 1468 (++iface->dhcpv6_sntp_cnt) * sizeof(*iface->dhcpv6_sntp)); 1469 if (!iface->dhcpv6_sntp) 1470 goto err; 1471 1472 iface->dhcpv6_sntp[iface->dhcpv6_sntp_cnt - 1] = addr6; 1473 1474 if (!parse_ntp_options(&iface->dhcpv6_ntp_len, addr6, &iface->dhcpv6_ntp)) 1475 iface->dhcpv6_ntp_cnt++; 1476 } else { 1477 if (!parse_ntp_fqdn(&iface->dhcpv6_ntp_len, str, &iface->dhcpv6_ntp)) 1478 iface->dhcpv6_ntp_cnt++; 1479 } 1480 } 1481 } 1482 1483 return 0; 1484 1485 err: 1486 close_interface(iface); 1487 return -1; 1488 } 1489 1490 static int set_interface(struct uci_section *s) 1491 { 1492 blob_buf_init(&b, 0); 1493 uci_to_blob(&b, s, &interface_attr_list); 1494 1495 return config_parse_interface(blob_data(b.head), blob_len(b.head), s->e.name, true); 1496 } 1497 1498 static void lease_delete_assignments(struct lease *l, bool v6) 1499 { 1500 struct dhcp_assignment *a, *tmp; 1501 unsigned int flag = v6 ? OAF_DHCPV6 : OAF_DHCPV4; 1502 1503 list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) { 1504 if (a->flags & flag) 1505 free_assignment(a); 1506 } 1507 } 1508 1509 static void lease_update_assignments(struct lease *l) 1510 { 1511 struct dhcp_assignment *a; 1512 1513 list_for_each_entry(a, &l->assignments, lease_list) { 1514 if (a->hostname) 1515 free(a->hostname); 1516 a->hostname = NULL; 1517 1518 if (l->hostname) 1519 a->hostname = strdup(l->hostname); 1520 1521 a->leasetime = l->leasetime; 1522 } 1523 } 1524 1525 static int lease_cmp(const void *k1, const void *k2, _unused void *ptr) 1526 { 1527 const struct lease *l1 = k1, *l2 = k2; 1528 int cmp = 0; 1529 1530 if (l1->duid_len != l2->duid_len) 1531 return l1->duid_len - l2->duid_len; 1532 1533 if (l1->duid_len && l2->duid_len) 1534 cmp = memcmp(l1->duid, l2->duid, l1->duid_len); 1535 1536 if (cmp) 1537 return cmp; 1538 1539 if (l1->mac_count != l2->mac_count) 1540 return l1->mac_count - l2->mac_count; 1541 1542 for (size_t i = 0; i < l1->mac_count; i++) { 1543 cmp = memcmp(l1->macs[i].ether_addr_octet, 1544 l2->macs[i].ether_addr_octet, 1545 sizeof(l1->macs[i].ether_addr_octet)); 1546 if (cmp) 1547 return cmp; 1548 } 1549 1550 return 0; 1551 } 1552 1553 static void lease_change_config(struct lease *l_old, struct lease *l_new) 1554 { 1555 bool update = false; 1556 1557 if ((!!l_new->hostname != !!l_old->hostname) || 1558 (l_new->hostname && strcmp(l_new->hostname, l_old->hostname))) { 1559 free(l_old->hostname); 1560 l_old->hostname = NULL; 1561 1562 if (l_new->hostname) 1563 l_old->hostname = strdup(l_new->hostname); 1564 1565 update = true; 1566 } 1567 1568 if (l_old->leasetime != l_new->leasetime) { 1569 l_old->leasetime = l_new->leasetime; 1570 update = true; 1571 } 1572 1573 if (l_old->ipaddr != l_new->ipaddr) { 1574 l_old->ipaddr = l_new->ipaddr; 1575 lease_delete_assignments(l_old, false); 1576 } 1577 1578 if (l_old->hostid != l_new->hostid) { 1579 l_old->hostid = l_new->hostid; 1580 lease_delete_assignments(l_old, true); 1581 } 1582 1583 if (update) 1584 lease_update_assignments(l_old); 1585 1586 free_lease(l_new); 1587 } 1588 1589 static void lease_delete(struct lease *l) 1590 { 1591 struct dhcp_assignment *a, *tmp; 1592 1593 list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) 1594 free_assignment(a); 1595 1596 free_lease(l); 1597 } 1598 1599 static void lease_update(_unused struct vlist_tree *tree, struct vlist_node *node_new, 1600 struct vlist_node *node_old) 1601 { 1602 struct lease *lease_new = container_of(node_new, struct lease, node); 1603 struct lease *lease_old = container_of(node_old, struct lease, node); 1604 1605 if (node_old && node_new) 1606 lease_change_config(lease_old, lease_new); 1607 else if (node_old) 1608 lease_delete(lease_old); 1609 } 1610 1611 struct lease *config_find_lease_by_duid(const uint8_t *duid, const uint16_t len) 1612 { 1613 struct lease *l; 1614 1615 vlist_for_each_element(&leases, l, node) { 1616 if (l->duid_len == len && !memcmp(l->duid, duid, len)) 1617 return l; 1618 } 1619 1620 return NULL; 1621 } 1622 1623 struct lease *config_find_lease_by_mac(const uint8_t *mac) 1624 { 1625 struct lease *l; 1626 1627 vlist_for_each_element(&leases, l, node) { 1628 for (size_t i = 0; i < l->mac_count; i++) { 1629 if (!memcmp(l->macs[i].ether_addr_octet, mac, 1630 sizeof(l->macs[i].ether_addr_octet))) 1631 return l; 1632 } 1633 } 1634 1635 return NULL; 1636 } 1637 1638 struct lease *config_find_lease_by_hostid(const uint64_t hostid) 1639 { 1640 struct lease *l; 1641 1642 vlist_for_each_element(&leases, l, node) { 1643 if (l->hostid == hostid) 1644 return l; 1645 } 1646 1647 return NULL; 1648 } 1649 1650 struct lease *config_find_lease_by_ipaddr(const uint32_t ipaddr) 1651 { 1652 struct lease *l; 1653 1654 vlist_for_each_element(&leases, l, node) { 1655 if (l->ipaddr == ipaddr) 1656 return l; 1657 } 1658 1659 return NULL; 1660 } 1661 1662 void reload_services(struct interface *iface) 1663 { 1664 if (iface->ifflags & IFF_RUNNING) { 1665 syslog(LOG_DEBUG, "Enabling services with %s running", iface->ifname); 1666 router_setup_interface(iface, iface->ra != MODE_DISABLED); 1667 dhcpv6_setup_interface(iface, iface->dhcpv6 != MODE_DISABLED); 1668 ndp_setup_interface(iface, iface->ndp != MODE_DISABLED); 1669 #ifdef DHCPV4_SUPPORT 1670 dhcpv4_setup_interface(iface, iface->dhcpv4 != MODE_DISABLED); 1671 #endif 1672 } else { 1673 syslog(LOG_DEBUG, "Disabling services with %s not running", iface->ifname); 1674 router_setup_interface(iface, false); 1675 dhcpv6_setup_interface(iface, false); 1676 ndp_setup_interface(iface, false); 1677 #ifdef DHCPV4_SUPPORT 1678 dhcpv4_setup_interface(iface, false); 1679 #endif 1680 } 1681 } 1682 1683 static int ipv6_pxe_from_uci(struct uci_section* s) 1684 { 1685 blob_buf_init(&b, 0); 1686 uci_to_blob(&b, s, &ipv6_pxe_attr_list); 1687 1688 void* data = blob_data(b.head); 1689 size_t len = blob_len(b.head); 1690 1691 struct blob_attr* tb[IFACE_ATTR_MAX]; 1692 blobmsg_parse(ipv6_pxe_attrs, IPV6_PXE_MAX, tb, data, len); 1693 1694 if (!tb[IPV6_PXE_URL]) 1695 return -1; 1696 1697 const char* url = blobmsg_get_string(tb[IPV6_PXE_URL]); 1698 1699 uint32_t arch = 0xFFFFFFFF; 1700 if (tb[IPV6_PXE_ARCH]) 1701 arch = blobmsg_get_u32(tb[IPV6_PXE_ARCH]); 1702 1703 return ipv6_pxe_entry_new(arch, url) ? -1 : 0; 1704 } 1705 1706 void odhcpd_reload(void) 1707 { 1708 struct uci_context *uci = uci_alloc_context(); 1709 struct interface *master = NULL, *i, *tmp; 1710 1711 if (!uci) 1712 return; 1713 1714 vlist_update(&leases); 1715 avl_for_each_element(&interfaces, i, avl) 1716 clean_interface(i); 1717 1718 struct uci_package *dhcp = NULL; 1719 if (!uci_load(uci, "dhcp", &dhcp)) { 1720 struct uci_element *e; 1721 1722 /* 1. Global settings */ 1723 uci_foreach_element(&dhcp->sections, e) { 1724 struct uci_section *s = uci_to_section(e); 1725 if (!strcmp(s->type, "odhcpd")) 1726 set_config(s); 1727 } 1728 1729 /* 2. DHCP pools */ 1730 uci_foreach_element(&dhcp->sections, e) { 1731 struct uci_section *s = uci_to_section(e); 1732 if (!strcmp(s->type, "dhcp")) 1733 set_interface(s); 1734 } 1735 1736 /* 3. Static leases */ 1737 uci_foreach_element(&dhcp->sections, e) { 1738 struct uci_section* s = uci_to_section(e); 1739 if (!strcmp(s->type, "host")) 1740 set_lease_from_uci(s); 1741 } 1742 1743 /* 4. IPv6 PxE */ 1744 ipv6_pxe_clear(); 1745 uci_foreach_element(&dhcp->sections, e) { 1746 struct uci_section* s = uci_to_section(e); 1747 if (!strcmp(s->type, "boot6")) 1748 ipv6_pxe_from_uci(s); 1749 } 1750 ipv6_pxe_dump(); 1751 } 1752 1753 if (config.dhcp_statefile) { 1754 char *path = strdup(config.dhcp_statefile); 1755 1756 mkdir_p(dirname(path), 0755); 1757 free(path); 1758 } 1759 1760 vlist_flush(&leases); 1761 1762 #ifdef WITH_UBUS 1763 ubus_apply_network(); 1764 #endif 1765 1766 bool any_dhcpv6_slave = false, any_ra_slave = false, any_ndp_slave = false; 1767 1768 /* Test for */ 1769 avl_for_each_element(&interfaces, i, avl) { 1770 if (i->master) 1771 continue; 1772 1773 if (i->dhcpv6 == MODE_HYBRID || i->dhcpv6 == MODE_RELAY) 1774 any_dhcpv6_slave = true; 1775 1776 if (i->ra == MODE_HYBRID || i->ra == MODE_RELAY) 1777 any_ra_slave = true; 1778 1779 if (i->ndp == MODE_HYBRID || i->ndp == MODE_RELAY) 1780 any_ndp_slave = true; 1781 } 1782 1783 /* Evaluate hybrid mode for master */ 1784 avl_for_each_element(&interfaces, i, avl) { 1785 if (!i->master) 1786 continue; 1787 1788 enum odhcpd_mode hybrid_mode = MODE_DISABLED; 1789 #ifdef WITH_UBUS 1790 if (!ubus_has_prefix(i->name, i->ifname)) 1791 hybrid_mode = MODE_RELAY; 1792 #endif 1793 1794 if (i->dhcpv6 == MODE_HYBRID) 1795 i->dhcpv6 = hybrid_mode; 1796 1797 if (i->dhcpv6 == MODE_RELAY && !any_dhcpv6_slave) 1798 i->dhcpv6 = MODE_DISABLED; 1799 1800 if (i->ra == MODE_HYBRID) 1801 i->ra = hybrid_mode; 1802 1803 if (i->ra == MODE_RELAY && !any_ra_slave) 1804 i->ra = MODE_DISABLED; 1805 1806 if (i->ndp == MODE_HYBRID) 1807 i->ndp = hybrid_mode; 1808 1809 if (i->ndp == MODE_RELAY && !any_ndp_slave) 1810 i->ndp = MODE_DISABLED; 1811 1812 if (i->dhcpv6 == MODE_RELAY || i->ra == MODE_RELAY || i->ndp == MODE_RELAY) 1813 master = i; 1814 } 1815 1816 1817 avl_for_each_element_safe(&interfaces, i, avl, tmp) { 1818 if (i->inuse && i->ifflags & IFF_RUNNING) { 1819 /* Resolve hybrid mode */ 1820 if (i->dhcpv6 == MODE_HYBRID) 1821 i->dhcpv6 = (master && master->dhcpv6 == MODE_RELAY) ? 1822 MODE_RELAY : MODE_SERVER; 1823 1824 if (i->ra == MODE_HYBRID) 1825 i->ra = (master && master->ra == MODE_RELAY) ? 1826 MODE_RELAY : MODE_SERVER; 1827 1828 if (i->ndp == MODE_HYBRID) 1829 i->ndp = (master && master->ndp == MODE_RELAY) ? 1830 MODE_RELAY : MODE_DISABLED; 1831 1832 reload_services(i); 1833 } else 1834 close_interface(i); 1835 } 1836 1837 uci_unload(uci, dhcp); 1838 uci_free_context(uci); 1839 } 1840 1841 static void handle_signal(int signal) 1842 { 1843 char b[1] = {0}; 1844 1845 if (signal == SIGHUP) { 1846 if (write(reload_pipe[1], b, sizeof(b)) < 0) {} 1847 } else 1848 uloop_end(); 1849 } 1850 1851 static void reload_cb(struct uloop_fd *u, _unused unsigned int events) 1852 { 1853 char b[512]; 1854 if (read(u->fd, b, sizeof(b)) < 0) {} 1855 1856 odhcpd_reload(); 1857 } 1858 1859 static struct uloop_fd reload_fd = { .fd = -1, .cb = reload_cb }; 1860 1861 void odhcpd_run(void) 1862 { 1863 if (pipe2(reload_pipe, O_NONBLOCK | O_CLOEXEC) < 0) {} 1864 1865 reload_fd.fd = reload_pipe[0]; 1866 uloop_fd_add(&reload_fd, ULOOP_READ); 1867 1868 signal(SIGTERM, handle_signal); 1869 signal(SIGINT, handle_signal); 1870 signal(SIGHUP, handle_signal); 1871 1872 #ifdef WITH_UBUS 1873 while (ubus_init()) 1874 sleep(1); 1875 #endif 1876 1877 odhcpd_reload(); 1878 uloop_run(); 1879 } 1880
This page was automatically generated by LXR 0.3.1. • OpenWrt