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 22 static struct blob_buf b; 23 static int reload_pipe[2] = { -1, -1 }; 24 25 static int lease_cmp(const void *k1, const void *k2, void *ptr); 26 static void lease_update(struct vlist_tree *tree, struct vlist_node *node_new, 27 struct vlist_node *node_old); 28 29 struct vlist_tree leases = VLIST_TREE_INIT(leases, lease_cmp, lease_update, true, false); 30 AVL_TREE(interfaces, avl_strcmp, false, NULL); 31 struct config config = {.legacy = false, .main_dhcpv4 = false, 32 .dhcp_cb = NULL, .dhcp_statefile = NULL, 33 .log_level = LOG_WARNING}; 34 35 #define START_DEFAULT 100 36 #define LIMIT_DEFAULT 150 37 38 #define HOSTID_LEN_MIN 12 39 #define HOSTID_LEN_MAX 64 40 #define HOSTID_LEN_DEFAULT HOSTID_LEN_MIN 41 42 #define OAF_DHCPV6 (OAF_DHCPV6_NA | OAF_DHCPV6_PD) 43 44 enum { 45 IFACE_ATTR_INTERFACE, 46 IFACE_ATTR_IFNAME, 47 IFACE_ATTR_NETWORKID, 48 IFACE_ATTR_DYNAMICDHCP, 49 IFACE_ATTR_LEASETIME, 50 IFACE_ATTR_LIMIT, 51 IFACE_ATTR_START, 52 IFACE_ATTR_MASTER, 53 IFACE_ATTR_UPSTREAM, 54 IFACE_ATTR_RA, 55 IFACE_ATTR_DHCPV4, 56 IFACE_ATTR_DHCPV6, 57 IFACE_ATTR_NDP, 58 IFACE_ATTR_ROUTER, 59 IFACE_ATTR_DNS, 60 IFACE_ATTR_DNS_SERVICE, 61 IFACE_ATTR_DOMAIN, 62 IFACE_ATTR_FILTER_CLASS, 63 IFACE_ATTR_DHCPV4_FORCERECONF, 64 IFACE_ATTR_DHCPV6_RAW, 65 IFACE_ATTR_DHCPV6_ASSIGNALL, 66 IFACE_ATTR_DHCPV6_PD, 67 IFACE_ATTR_DHCPV6_NA, 68 IFACE_ATTR_DHCPV6_HOSTID_LEN, 69 IFACE_ATTR_RA_DEFAULT, 70 IFACE_ATTR_RA_MANAGEMENT, 71 IFACE_ATTR_RA_FLAGS, 72 IFACE_ATTR_RA_SLAAC, 73 IFACE_ATTR_RA_OFFLINK, 74 IFACE_ATTR_RA_PREFERENCE, 75 IFACE_ATTR_RA_ADVROUTER, 76 IFACE_ATTR_RA_MININTERVAL, 77 IFACE_ATTR_RA_MAXINTERVAL, 78 IFACE_ATTR_RA_LIFETIME, 79 IFACE_ATTR_RA_USELEASETIME, 80 IFACE_ATTR_RA_REACHABLETIME, 81 IFACE_ATTR_RA_RETRANSTIME, 82 IFACE_ATTR_RA_HOPLIMIT, 83 IFACE_ATTR_RA_MTU, 84 IFACE_ATTR_RA_DNS, 85 IFACE_ATTR_PD_MANAGER, 86 IFACE_ATTR_PD_CER, 87 IFACE_ATTR_NDPROXY_ROUTING, 88 IFACE_ATTR_NDPROXY_SLAVE, 89 IFACE_ATTR_PREFIX_FILTER, 90 IFACE_ATTR_PREFERRED_LIFETIME, 91 IFACE_ATTR_NTP, 92 IFACE_ATTR_MAX 93 }; 94 95 static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { 96 [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING }, 97 [IFACE_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, 98 [IFACE_ATTR_NETWORKID] = { .name = "networkid", .type = BLOBMSG_TYPE_STRING }, 99 [IFACE_ATTR_DYNAMICDHCP] = { .name = "dynamicdhcp", .type = BLOBMSG_TYPE_BOOL }, 100 [IFACE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 101 [IFACE_ATTR_START] = { .name = "start", .type = BLOBMSG_TYPE_INT32 }, 102 [IFACE_ATTR_LIMIT] = { .name = "limit", .type = BLOBMSG_TYPE_INT32 }, 103 [IFACE_ATTR_MASTER] = { .name = "master", .type = BLOBMSG_TYPE_BOOL }, 104 [IFACE_ATTR_UPSTREAM] = { .name = "upstream", .type = BLOBMSG_TYPE_ARRAY }, 105 [IFACE_ATTR_RA] = { .name = "ra", .type = BLOBMSG_TYPE_STRING }, 106 [IFACE_ATTR_DHCPV4] = { .name = "dhcpv4", .type = BLOBMSG_TYPE_STRING }, 107 [IFACE_ATTR_DHCPV6] = { .name = "dhcpv6", .type = BLOBMSG_TYPE_STRING }, 108 [IFACE_ATTR_NDP] = { .name = "ndp", .type = BLOBMSG_TYPE_STRING }, 109 [IFACE_ATTR_ROUTER] = { .name = "router", .type = BLOBMSG_TYPE_ARRAY }, 110 [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY }, 111 [IFACE_ATTR_DNS_SERVICE] = { .name = "dns_service", .type = BLOBMSG_TYPE_BOOL }, 112 [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY }, 113 [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING }, 114 [IFACE_ATTR_DHCPV4_FORCERECONF] = { .name = "dhcpv4_forcereconf", .type = BLOBMSG_TYPE_BOOL }, 115 [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING }, 116 [IFACE_ATTR_DHCPV6_ASSIGNALL] = { .name ="dhcpv6_assignall", .type = BLOBMSG_TYPE_BOOL }, 117 [IFACE_ATTR_DHCPV6_PD] = { .name = "dhcpv6_pd", .type = BLOBMSG_TYPE_BOOL }, 118 [IFACE_ATTR_DHCPV6_NA] = { .name = "dhcpv6_na", .type = BLOBMSG_TYPE_BOOL }, 119 [IFACE_ATTR_DHCPV6_HOSTID_LEN] = { .name = "dhcpv6_hostidlength", .type = BLOBMSG_TYPE_INT32 }, 120 [IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = BLOBMSG_TYPE_STRING }, 121 [IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = BLOBMSG_TYPE_STRING }, 122 [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 }, 123 [IFACE_ATTR_RA_MANAGEMENT] = { .name = "ra_management", .type = BLOBMSG_TYPE_INT32 }, 124 [IFACE_ATTR_RA_FLAGS] = { .name = "ra_flags", . type = BLOBMSG_TYPE_ARRAY }, 125 [IFACE_ATTR_RA_SLAAC] = { .name = "ra_slaac", .type = BLOBMSG_TYPE_BOOL }, 126 [IFACE_ATTR_RA_OFFLINK] = { .name = "ra_offlink", .type = BLOBMSG_TYPE_BOOL }, 127 [IFACE_ATTR_RA_PREFERENCE] = { .name = "ra_preference", .type = BLOBMSG_TYPE_STRING }, 128 [IFACE_ATTR_RA_ADVROUTER] = { .name = "ra_advrouter", .type = BLOBMSG_TYPE_BOOL }, 129 [IFACE_ATTR_RA_MININTERVAL] = { .name = "ra_mininterval", .type = BLOBMSG_TYPE_INT32 }, 130 [IFACE_ATTR_RA_MAXINTERVAL] = { .name = "ra_maxinterval", .type = BLOBMSG_TYPE_INT32 }, 131 [IFACE_ATTR_RA_LIFETIME] = { .name = "ra_lifetime", .type = BLOBMSG_TYPE_INT32 }, 132 [IFACE_ATTR_RA_USELEASETIME] = { .name = "ra_useleasetime", .type = BLOBMSG_TYPE_BOOL }, 133 [IFACE_ATTR_RA_REACHABLETIME] = { .name = "ra_reachabletime", .type = BLOBMSG_TYPE_INT32 }, 134 [IFACE_ATTR_RA_RETRANSTIME] = { .name = "ra_retranstime", .type = BLOBMSG_TYPE_INT32 }, 135 [IFACE_ATTR_RA_HOPLIMIT] = { .name = "ra_hoplimit", .type = BLOBMSG_TYPE_INT32 }, 136 [IFACE_ATTR_RA_MTU] = { .name = "ra_mtu", .type = BLOBMSG_TYPE_INT32 }, 137 [IFACE_ATTR_RA_DNS] = { .name = "ra_dns", .type = BLOBMSG_TYPE_BOOL }, 138 [IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = BLOBMSG_TYPE_BOOL }, 139 [IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = BLOBMSG_TYPE_BOOL }, 140 [IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = BLOBMSG_TYPE_STRING }, 141 [IFACE_ATTR_PREFERRED_LIFETIME] = { .name = "preferred_lifetime", .type = BLOBMSG_TYPE_STRING }, 142 [IFACE_ATTR_NTP] = { .name = "ntp", .type = BLOBMSG_TYPE_ARRAY }, 143 }; 144 145 static const struct uci_blob_param_info iface_attr_info[IFACE_ATTR_MAX] = { 146 [IFACE_ATTR_UPSTREAM] = { .type = BLOBMSG_TYPE_STRING }, 147 [IFACE_ATTR_DNS] = { .type = BLOBMSG_TYPE_STRING }, 148 [IFACE_ATTR_DOMAIN] = { .type = BLOBMSG_TYPE_STRING }, 149 }; 150 151 const struct uci_blob_param_list interface_attr_list = { 152 .n_params = IFACE_ATTR_MAX, 153 .params = iface_attrs, 154 .info = iface_attr_info, 155 }; 156 157 const struct blobmsg_policy lease_attrs[LEASE_ATTR_MAX] = { 158 [LEASE_ATTR_IP] = { .name = "ip", .type = BLOBMSG_TYPE_STRING }, 159 [LEASE_ATTR_MAC] = { .name = "mac", .type = BLOBMSG_TYPE_STRING }, 160 [LEASE_ATTR_DUID] = { .name = "duid", .type = BLOBMSG_TYPE_STRING }, 161 [LEASE_ATTR_HOSTID] = { .name = "hostid", .type = BLOBMSG_TYPE_STRING }, 162 [LEASE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 163 [LEASE_ATTR_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 164 }; 165 166 const struct uci_blob_param_list lease_attr_list = { 167 .n_params = LEASE_ATTR_MAX, 168 .params = lease_attrs, 169 }; 170 171 enum { 172 ODHCPD_ATTR_LEGACY, 173 ODHCPD_ATTR_MAINDHCP, 174 ODHCPD_ATTR_LEASEFILE, 175 ODHCPD_ATTR_LEASETRIGGER, 176 ODHCPD_ATTR_LOGLEVEL, 177 ODHCPD_ATTR_MAX 178 }; 179 180 static const struct blobmsg_policy odhcpd_attrs[ODHCPD_ATTR_MAX] = { 181 [ODHCPD_ATTR_LEGACY] = { .name = "legacy", .type = BLOBMSG_TYPE_BOOL }, 182 [ODHCPD_ATTR_MAINDHCP] = { .name = "maindhcp", .type = BLOBMSG_TYPE_BOOL }, 183 [ODHCPD_ATTR_LEASEFILE] = { .name = "leasefile", .type = BLOBMSG_TYPE_STRING }, 184 [ODHCPD_ATTR_LEASETRIGGER] = { .name = "leasetrigger", .type = BLOBMSG_TYPE_STRING }, 185 [ODHCPD_ATTR_LOGLEVEL] = { .name = "loglevel", .type = BLOBMSG_TYPE_INT32 }, 186 }; 187 188 const struct uci_blob_param_list odhcpd_attr_list = { 189 .n_params = ODHCPD_ATTR_MAX, 190 .params = odhcpd_attrs, 191 }; 192 193 static const struct { const char *name; uint8_t flag; } ra_flags[] = { 194 { .name = "managed-config", .flag = ND_RA_FLAG_MANAGED }, 195 { .name = "other-config", .flag = ND_RA_FLAG_OTHER }, 196 { .name = "home-agent", .flag = ND_RA_FLAG_HOME_AGENT }, 197 { .name = "none", . flag = 0 }, 198 { .name = NULL, }, 199 }; 200 201 static void set_interface_defaults(struct interface *iface) 202 { 203 iface->ignore = true; 204 iface->dhcpv4 = MODE_DISABLED; 205 iface->dhcpv6 = MODE_DISABLED; 206 iface->ra = MODE_DISABLED; 207 iface->ndp = MODE_DISABLED; 208 iface->learn_routes = 1; 209 iface->dhcp_leasetime = 43200; 210 iface->preferred_lifetime = 43200; 211 iface->dhcpv4_start.s_addr = htonl(START_DEFAULT); 212 iface->dhcpv4_end.s_addr = htonl(START_DEFAULT + LIMIT_DEFAULT - 1); 213 iface->dhcpv6_assignall = true; 214 iface->dhcpv6_pd = true; 215 iface->dhcpv6_na = true; 216 iface->dhcpv6_hostid_len = HOSTID_LEN_DEFAULT; 217 iface->dns_service = true; 218 iface->ra_flags = ND_RA_FLAG_OTHER; 219 iface->ra_slaac = true; 220 iface->ra_maxinterval = 600; 221 iface->ra_mininterval = iface->ra_maxinterval/3; 222 iface->ra_lifetime = -1; 223 iface->ra_dns = true; 224 } 225 226 static void clean_interface(struct interface *iface) 227 { 228 free(iface->dns); 229 free(iface->search); 230 free(iface->upstream); 231 free(iface->dhcpv4_router); 232 free(iface->dhcpv4_dns); 233 free(iface->dhcpv6_raw); 234 free(iface->filter_class); 235 free(iface->dhcpv4_ntp); 236 free(iface->dhcpv6_ntp); 237 free(iface->dhcpv6_sntp); 238 memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra)); 239 set_interface_defaults(iface); 240 } 241 242 static void close_interface(struct interface *iface) 243 { 244 avl_delete(&interfaces, &iface->avl); 245 246 router_setup_interface(iface, false); 247 dhcpv6_setup_interface(iface, false); 248 ndp_setup_interface(iface, false); 249 #ifdef DHCPV4_SUPPORT 250 dhcpv4_setup_interface(iface, false); 251 #endif 252 253 clean_interface(iface); 254 free(iface->addr4); 255 free(iface->addr6); 256 free(iface->invalid_addr6); 257 free(iface->ifname); 258 free(iface); 259 } 260 261 static int parse_mode(const char *mode) 262 { 263 if (!strcmp(mode, "disabled")) 264 return MODE_DISABLED; 265 else if (!strcmp(mode, "server")) 266 return MODE_SERVER; 267 else if (!strcmp(mode, "relay")) 268 return MODE_RELAY; 269 else if (!strcmp(mode, "hybrid")) 270 return MODE_HYBRID; 271 else 272 return -1; 273 } 274 275 static int parse_ra_flags(uint8_t *flags, struct blob_attr *attr) 276 { 277 struct blob_attr *cur; 278 unsigned rem; 279 280 blobmsg_for_each_attr(cur, attr, rem) { 281 int i; 282 283 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 284 continue; 285 286 if (!blobmsg_check_attr(cur, false)) 287 continue; 288 289 for (i = 0; ra_flags[i].name; i++) { 290 if (!strcmp(ra_flags[i].name, blobmsg_get_string(cur))) { 291 *flags |= ra_flags[i].flag; 292 break; 293 } 294 } 295 296 if (!ra_flags[i].name) 297 return -1; 298 } 299 300 return 0; 301 } 302 303 static void set_config(struct uci_section *s) 304 { 305 struct blob_attr *tb[ODHCPD_ATTR_MAX], *c; 306 307 blob_buf_init(&b, 0); 308 uci_to_blob(&b, s, &odhcpd_attr_list); 309 blobmsg_parse(odhcpd_attrs, ODHCPD_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head)); 310 311 if ((c = tb[ODHCPD_ATTR_LEGACY])) 312 config.legacy = blobmsg_get_bool(c); 313 314 if ((c = tb[ODHCPD_ATTR_MAINDHCP])) 315 config.main_dhcpv4 = blobmsg_get_bool(c); 316 317 if ((c = tb[ODHCPD_ATTR_LEASEFILE])) { 318 free(config.dhcp_statefile); 319 config.dhcp_statefile = strdup(blobmsg_get_string(c)); 320 } 321 322 if ((c = tb[ODHCPD_ATTR_LEASETRIGGER])) { 323 free(config.dhcp_cb); 324 config.dhcp_cb = strdup(blobmsg_get_string(c)); 325 } 326 327 if ((c = tb[ODHCPD_ATTR_LOGLEVEL])) { 328 int log_level = (blobmsg_get_u32(c) & LOG_PRIMASK); 329 330 if (config.log_level != log_level) { 331 config.log_level = log_level; 332 setlogmask(LOG_UPTO(config.log_level)); 333 } 334 } 335 } 336 337 static double parse_leasetime(struct blob_attr *c) { 338 char *val = blobmsg_get_string(c), *endptr = NULL; 339 double time = strcmp(val, "infinite") ? strtod(val, &endptr) : UINT32_MAX; 340 341 if (time && endptr && endptr[0]) { 342 if (endptr[0] == 's') 343 time *= 1; 344 else if (endptr[0] == 'm') 345 time *= 60; 346 else if (endptr[0] == 'h') 347 time *= 3600; 348 else if (endptr[0] == 'd') 349 time *= 24 * 3600; 350 else if (endptr[0] == 'w') 351 time *= 7 * 24 * 3600; 352 else 353 goto err; 354 } 355 356 if (time < 60) 357 time = 60; 358 359 return time; 360 361 err: 362 return -1; 363 } 364 365 static void free_lease(struct lease *l) 366 { 367 free(l->hostname); 368 free(l); 369 } 370 371 372 int set_lease_from_blobmsg(struct blob_attr *ba) 373 { 374 struct blob_attr *tb[LEASE_ATTR_MAX], *c; 375 struct lease *l; 376 size_t duidlen = 0; 377 uint8_t *duid; 378 379 blobmsg_parse(lease_attrs, LEASE_ATTR_MAX, tb, blob_data(ba), blob_len(ba)); 380 381 if ((c = tb[LEASE_ATTR_DUID])) 382 duidlen = (blobmsg_data_len(c) - 1) / 2; 383 384 l = calloc_a(sizeof(*l), &duid, duidlen); 385 if (!l) 386 goto err; 387 388 if ((c = tb[LEASE_ATTR_MAC])) 389 if (!ether_aton_r(blobmsg_get_string(c), &l->mac)) 390 goto err; 391 392 if ((c = tb[LEASE_ATTR_DUID])) { 393 ssize_t len; 394 395 l->duid = duid; 396 len = odhcpd_unhexlify(l->duid, duidlen, blobmsg_get_string(c)); 397 398 if (len < 0) 399 goto err; 400 401 l->duid_len = len; 402 } 403 404 if ((c = tb[LEASE_ATTR_NAME])) { 405 l->hostname = strdup(blobmsg_get_string(c)); 406 if (!l->hostname || !odhcpd_valid_hostname(l->hostname)) 407 goto err; 408 } 409 410 if ((c = tb[LEASE_ATTR_IP])) 411 if (inet_pton(AF_INET, blobmsg_get_string(c), &l->ipaddr) < 0) 412 goto err; 413 414 if ((c = tb[LEASE_ATTR_HOSTID])) { 415 errno = 0; 416 l->hostid = strtoull(blobmsg_get_string(c), NULL, 16); 417 if (errno) 418 goto err; 419 } else { 420 uint32_t i4a = ntohl(l->ipaddr) & 0xff; 421 l->hostid = ((i4a / 100) << 8) | (((i4a % 100) / 10) << 4) | (i4a % 10); 422 } 423 424 if ((c = tb[LEASE_ATTR_LEASETIME])) { 425 double time = parse_leasetime(c); 426 if (time < 0) 427 goto err; 428 429 l->leasetime = time; 430 } 431 432 INIT_LIST_HEAD(&l->assignments); 433 vlist_add(&leases, &l->node, l); 434 return 0; 435 436 err: 437 if (l) 438 free_lease(l); 439 440 return -1; 441 } 442 443 static int set_lease_from_uci(struct uci_section *s) 444 { 445 blob_buf_init(&b, 0); 446 uci_to_blob(&b, s, &lease_attr_list); 447 448 return set_lease_from_blobmsg(b.head); 449 } 450 451 /* Parse NTP Options for DHCPv6 Address */ 452 static int parse_ntp_options(uint16_t *dhcpv6_ntp_len, struct in6_addr addr6, uint8_t **dhcpv6_ntp) 453 { 454 uint16_t sub_opt = 0, sub_len = htons(IPV6_ADDR_LEN); 455 uint16_t ntp_len = IPV6_ADDR_LEN + 4; 456 uint8_t *ntp = *dhcpv6_ntp; 457 size_t pos = *dhcpv6_ntp_len; 458 459 ntp = realloc(ntp, pos + ntp_len); 460 if (!ntp) 461 return -1; 462 463 *dhcpv6_ntp = ntp; 464 465 if (IN6_IS_ADDR_MULTICAST(&addr6)) 466 sub_opt = htons(NTP_SUBOPTION_MC_ADDR); 467 else 468 sub_opt = htons(NTP_SUBOPTION_SRV_ADDR); 469 470 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 471 pos += sizeof(sub_opt); 472 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 473 pos += sizeof(sub_len); 474 memcpy(ntp + pos, &addr6, IPV6_ADDR_LEN); 475 476 *dhcpv6_ntp_len += ntp_len; 477 478 return 0; 479 } 480 481 /* Parse NTP Options for FQDN */ 482 static int parse_ntp_fqdn(uint16_t *dhcpv6_ntp_len, char *fqdn, uint8_t **dhcpv6_ntp) 483 { 484 size_t fqdn_len = strlen(fqdn); 485 uint16_t sub_opt = 0, sub_len = 0, ntp_len = 0; 486 uint8_t *ntp = *dhcpv6_ntp; 487 size_t pos = *dhcpv6_ntp_len; 488 uint8_t buf[256] = {0}; 489 490 if (fqdn_len > 0 && fqdn[fqdn_len - 1] == '.') 491 fqdn[fqdn_len - 1] = 0; 492 493 int len = dn_comp(fqdn, buf, sizeof(buf), NULL, NULL); 494 if (len <= 0) 495 return -1; 496 497 ntp_len = len + 4; 498 499 ntp = realloc(ntp, pos + ntp_len); 500 if (!ntp) 501 return -1; 502 503 *dhcpv6_ntp = ntp; 504 505 sub_opt = htons(NTP_SUBOPTION_SRV_FQDN); 506 sub_len = htons(len); 507 508 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 509 pos += sizeof(sub_opt); 510 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 511 pos += sizeof(sub_len); 512 memcpy(ntp + pos, buf, len); 513 514 *dhcpv6_ntp_len += ntp_len; 515 516 return 0; 517 } 518 519 int config_parse_interface(void *data, size_t len, const char *name, bool overwrite) 520 { 521 struct interface *iface; 522 struct blob_attr *tb[IFACE_ATTR_MAX], *c; 523 bool get_addrs = false; 524 int mode; 525 const char *ifname = NULL; 526 527 blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, data, len); 528 529 if (tb[IFACE_ATTR_INTERFACE]) 530 name = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]); 531 532 if (!name) 533 return -1; 534 535 iface = avl_find_element(&interfaces, name, iface, avl); 536 if (!iface) { 537 char *new_name; 538 539 iface = calloc_a(sizeof(*iface), &new_name, strlen(name) + 1); 540 if (!iface) 541 return -1; 542 543 iface->name = strcpy(new_name, name); 544 iface->avl.key = iface->name; 545 iface->router_event.uloop.fd = -1; 546 iface->dhcpv6_event.uloop.fd = -1; 547 iface->ndp_event.uloop.fd = -1; 548 iface->ndp_ping_fd = -1; 549 iface->dhcpv4_event.uloop.fd = -1; 550 INIT_LIST_HEAD(&iface->ia_assignments); 551 INIT_LIST_HEAD(&iface->dhcpv4_assignments); 552 INIT_LIST_HEAD(&iface->dhcpv4_fr_ips); 553 554 set_interface_defaults(iface); 555 556 avl_insert(&interfaces, &iface->avl); 557 get_addrs = overwrite = true; 558 } 559 560 if (overwrite) { 561 if ((c = tb[IFACE_ATTR_IFNAME])) 562 ifname = blobmsg_get_string(c); 563 else if ((c = tb[IFACE_ATTR_NETWORKID])) 564 ifname = blobmsg_get_string(c); 565 } 566 567 #ifdef WITH_UBUS 568 if (overwrite || !iface->ifname) 569 ifname = ubus_get_ifname(name); 570 #endif 571 572 if (!iface->ifname && !ifname) 573 goto err; 574 575 if (ifname) { 576 free(iface->ifname); 577 iface->ifname = strdup(ifname); 578 579 if (!iface->ifname) 580 goto err; 581 582 if (!iface->ifindex && 583 (iface->ifindex = if_nametoindex(iface->ifname)) <= 0) 584 goto err; 585 } 586 587 if (get_addrs) { 588 ssize_t len = netlink_get_interface_addrs(iface->ifindex, 589 true, &iface->addr6); 590 591 if (len > 0) 592 iface->addr6_len = len; 593 594 len = netlink_get_interface_addrs(iface->ifindex, 595 false, &iface->addr4); 596 if (len > 0) 597 iface->addr4_len = len; 598 } 599 600 iface->inuse = true; 601 602 if ((c = tb[IFACE_ATTR_DYNAMICDHCP])) 603 iface->no_dynamic_dhcp = !blobmsg_get_bool(c); 604 605 if ((c = tb[IFACE_ATTR_LEASETIME])) { 606 double time = parse_leasetime(c); 607 608 if (time >= 0) 609 iface->dhcp_leasetime = time; 610 else 611 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 612 iface_attrs[IFACE_ATTR_LEASETIME].name, iface->name); 613 614 } 615 616 if ((c = tb[IFACE_ATTR_PREFERRED_LIFETIME])) { 617 double time = parse_leasetime(c); 618 619 if (time >= 0) 620 iface->preferred_lifetime = time; 621 else 622 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 623 iface_attrs[IFACE_ATTR_PREFERRED_LIFETIME].name, iface->name); 624 625 } 626 627 if ((c = tb[IFACE_ATTR_START])) { 628 iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c)); 629 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) + 630 LIMIT_DEFAULT - 1); 631 632 if (config.main_dhcpv4 && config.legacy) 633 iface->dhcpv4 = MODE_SERVER; 634 } 635 636 if ((c = tb[IFACE_ATTR_LIMIT])) 637 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) + 638 blobmsg_get_u32(c) - 1); 639 640 if ((c = tb[IFACE_ATTR_MASTER])) 641 iface->master = blobmsg_get_bool(c); 642 643 if (overwrite && (c = tb[IFACE_ATTR_UPSTREAM])) { 644 struct blob_attr *cur; 645 unsigned rem; 646 647 blobmsg_for_each_attr(cur, c, rem) { 648 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 649 continue; 650 651 iface->upstream = realloc(iface->upstream, 652 iface->upstream_len + blobmsg_data_len(cur)); 653 if (!iface->upstream) 654 goto err; 655 656 memcpy(iface->upstream + iface->upstream_len, blobmsg_get_string(cur), blobmsg_data_len(cur)); 657 iface->upstream_len += blobmsg_data_len(cur); 658 } 659 } 660 661 if ((c = tb[IFACE_ATTR_RA])) { 662 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 663 iface->ra = mode; 664 665 if (iface->ra != MODE_DISABLED) 666 iface->ignore = false; 667 } else 668 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 669 iface_attrs[IFACE_ATTR_RA].name, iface->name); 670 } 671 672 if ((c = tb[IFACE_ATTR_DHCPV4])) { 673 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 674 if (config.main_dhcpv4) { 675 iface->dhcpv4 = mode; 676 677 if (iface->dhcpv4 != MODE_DISABLED) 678 iface->ignore = false; 679 } 680 } else 681 syslog(LOG_ERR, "Invalid %s mode configured for interface %s", 682 iface_attrs[IFACE_ATTR_DHCPV4].name, iface->name); 683 } 684 685 if ((c = tb[IFACE_ATTR_DHCPV6])) { 686 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 687 iface->dhcpv6 = mode; 688 689 if (iface->dhcpv6 != MODE_DISABLED) 690 iface->ignore = false; 691 } else 692 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 693 iface_attrs[IFACE_ATTR_DHCPV6].name, iface->name); 694 } 695 696 if ((c = tb[IFACE_ATTR_NDP])) { 697 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 698 iface->ndp = mode; 699 700 if (iface->ndp != MODE_DISABLED) 701 iface->ignore = false; 702 } else 703 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 704 iface_attrs[IFACE_ATTR_NDP].name, iface->name); 705 } 706 707 if ((c = tb[IFACE_ATTR_ROUTER])) { 708 struct blob_attr *cur; 709 unsigned rem; 710 711 blobmsg_for_each_attr(cur, c, rem) { 712 struct in_addr addr4; 713 714 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 715 continue; 716 717 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 718 iface->dhcpv4_router = realloc(iface->dhcpv4_router, 719 (++iface->dhcpv4_router_cnt) * sizeof(*iface->dhcpv4_router)); 720 if (!iface->dhcpv4_router) 721 goto err; 722 723 iface->dhcpv4_router[iface->dhcpv4_router_cnt - 1] = addr4; 724 } else 725 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 726 iface_attrs[IFACE_ATTR_ROUTER].name, iface->name); 727 } 728 } 729 730 if ((c = tb[IFACE_ATTR_DNS])) { 731 struct blob_attr *cur; 732 unsigned rem; 733 734 iface->always_rewrite_dns = true; 735 blobmsg_for_each_attr(cur, c, rem) { 736 struct in_addr addr4; 737 struct in6_addr addr6; 738 739 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 740 continue; 741 742 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 743 if (addr4.s_addr == INADDR_ANY) { 744 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 745 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 746 747 continue; 748 } 749 750 iface->dhcpv4_dns = realloc(iface->dhcpv4_dns, 751 (++iface->dhcpv4_dns_cnt) * sizeof(*iface->dhcpv4_dns)); 752 if (!iface->dhcpv4_dns) 753 goto err; 754 755 iface->dhcpv4_dns[iface->dhcpv4_dns_cnt - 1] = addr4; 756 } else if (inet_pton(AF_INET6, blobmsg_get_string(cur), &addr6) == 1) { 757 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { 758 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 759 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 760 761 continue; 762 } 763 764 iface->dns = realloc(iface->dns, 765 (++iface->dns_cnt) * sizeof(*iface->dns)); 766 if (!iface->dns) 767 goto err; 768 769 iface->dns[iface->dns_cnt - 1] = addr6; 770 } else 771 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 772 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 773 } 774 } 775 776 if ((c = tb[IFACE_ATTR_DNS_SERVICE])) 777 iface->dns_service = blobmsg_get_bool(c); 778 779 if ((c = tb[IFACE_ATTR_DOMAIN])) { 780 struct blob_attr *cur; 781 unsigned rem; 782 783 blobmsg_for_each_attr(cur, c, rem) { 784 uint8_t buf[256]; 785 char *domain = blobmsg_get_string(cur); 786 size_t domainlen = strlen(domain); 787 int len; 788 789 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 790 continue; 791 792 domain = blobmsg_get_string(cur); 793 domainlen = strlen(domain); 794 795 if (domainlen > 0 && domain[domainlen - 1] == '.') 796 domain[domainlen - 1] = 0; 797 798 len = dn_comp(domain, buf, sizeof(buf), NULL, NULL); 799 if (len <= 0) { 800 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 801 iface_attrs[IFACE_ATTR_DOMAIN].name, iface->name); 802 803 continue; 804 } 805 806 iface->search = realloc(iface->search, iface->search_len + len); 807 if (!iface->search) 808 goto err; 809 810 memcpy(&iface->search[iface->search_len], buf, len); 811 iface->search_len += len; 812 } 813 } 814 815 if ((c = tb[IFACE_ATTR_FILTER_CLASS])) { 816 iface->filter_class = realloc(iface->filter_class, blobmsg_data_len(c) + 1); 817 memcpy(iface->filter_class, blobmsg_get_string(c), blobmsg_data_len(c) + 1); 818 } 819 820 if ((c = tb[IFACE_ATTR_DHCPV4_FORCERECONF])) 821 iface->dhcpv4_forcereconf = blobmsg_get_bool(c); 822 823 if ((c = tb[IFACE_ATTR_DHCPV6_RAW])) { 824 iface->dhcpv6_raw_len = blobmsg_data_len(c) / 2; 825 iface->dhcpv6_raw = realloc(iface->dhcpv6_raw, iface->dhcpv6_raw_len); 826 odhcpd_unhexlify(iface->dhcpv6_raw, iface->dhcpv6_raw_len, blobmsg_get_string(c)); 827 } 828 829 if ((c = tb[IFACE_ATTR_DHCPV6_ASSIGNALL])) 830 iface->dhcpv6_assignall = blobmsg_get_bool(c); 831 832 if ((c = tb[IFACE_ATTR_DHCPV6_PD])) 833 iface->dhcpv6_pd = blobmsg_get_bool(c); 834 835 if ((c = tb[IFACE_ATTR_DHCPV6_NA])) 836 iface->dhcpv6_na = blobmsg_get_bool(c); 837 838 if ((c = tb[IFACE_ATTR_DHCPV6_HOSTID_LEN])) { 839 uint32_t hostid_len = blobmsg_get_u32(c); 840 841 if (hostid_len >= HOSTID_LEN_MIN && hostid_len <= HOSTID_LEN_MAX) 842 iface->dhcpv6_hostid_len = hostid_len; 843 else 844 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 845 iface_attrs[IFACE_ATTR_DHCPV6_HOSTID_LEN].name, iface->name); 846 847 } 848 849 if ((c = tb[IFACE_ATTR_RA_DEFAULT])) 850 iface->default_router = blobmsg_get_u32(c); 851 852 if (!tb[IFACE_ATTR_RA_FLAGS] && !tb[IFACE_ATTR_RA_SLAAC] && 853 (c = tb[IFACE_ATTR_RA_MANAGEMENT])) { 854 switch (blobmsg_get_u32(c)) { 855 case 0: 856 iface->ra_flags = ND_RA_FLAG_OTHER; 857 iface->ra_slaac = true; 858 break; 859 case 1: 860 iface->ra_flags = ND_RA_FLAG_OTHER|ND_RA_FLAG_MANAGED; 861 iface->ra_slaac = true; 862 break; 863 case 2: 864 iface->ra_flags = ND_RA_FLAG_OTHER|ND_RA_FLAG_MANAGED; 865 iface->ra_slaac = false; 866 break; 867 default: 868 break; 869 } 870 } 871 872 if ((c = tb[IFACE_ATTR_RA_FLAGS])) { 873 iface->ra_flags = 0; 874 875 if (parse_ra_flags(&iface->ra_flags, c) < 0) 876 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 877 iface_attrs[IFACE_ATTR_RA_FLAGS].name, iface->name); 878 } 879 880 if ((c = tb[IFACE_ATTR_RA_REACHABLETIME])) { 881 uint32_t ra_reachabletime = blobmsg_get_u32(c); 882 883 if (ra_reachabletime <= 3600000) 884 iface->ra_reachabletime = ra_reachabletime; 885 else 886 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 887 iface_attrs[IFACE_ATTR_RA_REACHABLETIME].name, iface->name); 888 } 889 890 if ((c = tb[IFACE_ATTR_RA_RETRANSTIME])) { 891 uint32_t ra_retranstime = blobmsg_get_u32(c); 892 893 if (ra_retranstime <= 60000) 894 iface->ra_retranstime = ra_retranstime; 895 else 896 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 897 iface_attrs[IFACE_ATTR_RA_RETRANSTIME].name, iface->name); 898 } 899 900 if ((c = tb[IFACE_ATTR_RA_HOPLIMIT])) { 901 uint32_t ra_hoplimit = blobmsg_get_u32(c); 902 903 if (ra_hoplimit <= 255) 904 iface->ra_hoplimit = ra_hoplimit; 905 else 906 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 907 iface_attrs[IFACE_ATTR_RA_HOPLIMIT].name, iface->name); 908 } 909 910 if ((c = tb[IFACE_ATTR_RA_MTU])) { 911 uint32_t ra_mtu = blobmsg_get_u32(c); 912 913 if (ra_mtu >= 1280 || ra_mtu <= 65535) 914 iface->ra_mtu = ra_mtu; 915 else 916 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 917 iface_attrs[IFACE_ATTR_RA_MTU].name, iface->name); 918 } 919 920 if ((c = tb[IFACE_ATTR_RA_SLAAC])) 921 iface->ra_slaac = blobmsg_get_bool(c); 922 923 if ((c = tb[IFACE_ATTR_RA_OFFLINK])) 924 iface->ra_not_onlink = blobmsg_get_bool(c); 925 926 if ((c = tb[IFACE_ATTR_RA_ADVROUTER])) 927 iface->ra_advrouter = blobmsg_get_bool(c); 928 929 if ((c = tb[IFACE_ATTR_RA_MININTERVAL])) 930 iface->ra_mininterval = blobmsg_get_u32(c); 931 932 if ((c = tb[IFACE_ATTR_RA_MAXINTERVAL])) 933 iface->ra_maxinterval = blobmsg_get_u32(c); 934 935 if ((c = tb[IFACE_ATTR_RA_LIFETIME])) 936 iface->ra_lifetime = blobmsg_get_u32(c); 937 938 if ((c = tb[IFACE_ATTR_RA_USELEASETIME])) 939 iface->ra_useleasetime = blobmsg_get_bool(c); 940 941 if ((c = tb[IFACE_ATTR_RA_DNS])) 942 iface->ra_dns = blobmsg_get_bool(c); 943 944 if ((c = tb[IFACE_ATTR_RA_PREFERENCE])) { 945 const char *prio = blobmsg_get_string(c); 946 947 if (!strcmp(prio, "high")) 948 iface->route_preference = 1; 949 else if (!strcmp(prio, "low")) 950 iface->route_preference = -1; 951 else if (!strcmp(prio, "medium") || !strcmp(prio, "default")) 952 iface->route_preference = 0; 953 else 954 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 955 iface_attrs[IFACE_ATTR_RA_PREFERENCE].name, iface->name); 956 } 957 958 if ((c = tb[IFACE_ATTR_PD_MANAGER])) 959 strncpy(iface->dhcpv6_pd_manager, blobmsg_get_string(c), 960 sizeof(iface->dhcpv6_pd_manager) - 1); 961 962 if ((c = tb[IFACE_ATTR_PD_CER]) && 963 inet_pton(AF_INET6, blobmsg_get_string(c), &iface->dhcpv6_pd_cer) < 1) 964 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 965 iface_attrs[IFACE_ATTR_PD_CER].name, iface->name); 966 967 if ((c = tb[IFACE_ATTR_NDPROXY_ROUTING])) 968 iface->learn_routes = blobmsg_get_bool(c); 969 970 if ((c = tb[IFACE_ATTR_NDPROXY_SLAVE])) 971 iface->external = blobmsg_get_bool(c); 972 973 if ((c = tb[IFACE_ATTR_PREFIX_FILTER])) { 974 const char *str = blobmsg_get_string(c); 975 char *astr = malloc(strlen(str) + 1); 976 char *delim; 977 int l; 978 979 if (!astr || !strcpy(astr, str) || 980 (delim = strchr(astr, '/')) == NULL || (*(delim++) = 0) || 981 sscanf(delim, "%i", &l) == 0 || l > 128 || 982 inet_pton(AF_INET6, astr, &iface->pio_filter_addr) == 0) 983 iface->pio_filter_length = 0; 984 else 985 iface->pio_filter_length = l; 986 987 if (astr) 988 free(astr); 989 } 990 991 if (overwrite && (c = tb[IFACE_ATTR_NTP])) { 992 struct blob_attr *cur; 993 unsigned rem; 994 995 blobmsg_for_each_attr(cur, c, rem) { 996 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 997 continue; 998 999 char *str = blobmsg_get_string(cur); 1000 struct in_addr addr4; 1001 struct in6_addr addr6; 1002 1003 if (inet_pton(AF_INET, str, &addr4) == 1) { 1004 if (addr4.s_addr == INADDR_ANY) 1005 goto err; 1006 1007 iface->dhcpv4_ntp = realloc(iface->dhcpv4_ntp, 1008 (++iface->dhcpv4_ntp_cnt) * sizeof(*iface->dhcpv4_ntp)); 1009 if (!iface->dhcpv4_ntp) 1010 goto err; 1011 1012 iface->dhcpv4_ntp[iface->dhcpv4_ntp_cnt - 1] = addr4; 1013 } else if (inet_pton(AF_INET6, str, &addr6) == 1) { 1014 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) 1015 goto err; 1016 1017 iface->dhcpv6_sntp = realloc(iface->dhcpv6_sntp, 1018 (++iface->dhcpv6_sntp_cnt) * sizeof(*iface->dhcpv6_sntp)); 1019 if (!iface->dhcpv6_sntp) 1020 goto err; 1021 1022 iface->dhcpv6_sntp[iface->dhcpv6_sntp_cnt - 1] = addr6; 1023 1024 if (!parse_ntp_options(&iface->dhcpv6_ntp_len, addr6, &iface->dhcpv6_ntp)) 1025 iface->dhcpv6_ntp_cnt++; 1026 } else { 1027 if (!parse_ntp_fqdn(&iface->dhcpv6_ntp_len, str, &iface->dhcpv6_ntp)) 1028 iface->dhcpv6_ntp_cnt++; 1029 } 1030 } 1031 } 1032 1033 return 0; 1034 1035 err: 1036 close_interface(iface); 1037 return -1; 1038 } 1039 1040 static int set_interface(struct uci_section *s) 1041 { 1042 blob_buf_init(&b, 0); 1043 uci_to_blob(&b, s, &interface_attr_list); 1044 1045 return config_parse_interface(blob_data(b.head), blob_len(b.head), s->e.name, true); 1046 } 1047 1048 static void lease_delete_assignments(struct lease *l, bool v6) 1049 { 1050 struct dhcp_assignment *a, *tmp; 1051 unsigned int flag = v6 ? OAF_DHCPV6 : OAF_DHCPV4; 1052 1053 list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) { 1054 if (a->flags & flag) 1055 free_assignment(a); 1056 } 1057 } 1058 1059 static void lease_update_assignments(struct lease *l) 1060 { 1061 struct dhcp_assignment *a; 1062 1063 list_for_each_entry(a, &l->assignments, lease_list) { 1064 if (a->hostname) 1065 free(a->hostname); 1066 a->hostname = NULL; 1067 1068 if (l->hostname) 1069 a->hostname = strdup(l->hostname); 1070 1071 a->leasetime = l->leasetime; 1072 } 1073 } 1074 1075 static int lease_cmp(const void *k1, const void *k2, _unused void *ptr) 1076 { 1077 const struct lease *l1 = k1, *l2 = k2; 1078 int cmp = 0; 1079 1080 if (l1->duid_len != l2->duid_len) 1081 return l1->duid_len - l2->duid_len; 1082 1083 if (l1->duid_len && l2->duid_len) 1084 cmp = memcmp(l1->duid, l2->duid, l1->duid_len); 1085 1086 if (cmp) 1087 return cmp; 1088 1089 return memcmp(l1->mac.ether_addr_octet, l2->mac.ether_addr_octet, 1090 sizeof(l1->mac.ether_addr_octet)); 1091 } 1092 1093 static void lease_change_config(struct lease *l_old, struct lease *l_new) 1094 { 1095 bool update = false; 1096 1097 if ((!!l_new->hostname != !!l_old->hostname) || 1098 (l_new->hostname && strcmp(l_new->hostname, l_old->hostname))) { 1099 free(l_old->hostname); 1100 l_old->hostname = NULL; 1101 1102 if (l_new->hostname) 1103 l_old->hostname = strdup(l_new->hostname); 1104 1105 update = true; 1106 } 1107 1108 if (l_old->leasetime != l_new->leasetime) { 1109 l_old->leasetime = l_new->leasetime; 1110 update = true; 1111 } 1112 1113 if (l_old->ipaddr != l_new->ipaddr) { 1114 l_old->ipaddr = l_new->ipaddr; 1115 lease_delete_assignments(l_old, false); 1116 } 1117 1118 if (l_old->hostid != l_new->hostid) { 1119 l_old->hostid = l_new->hostid; 1120 lease_delete_assignments(l_old, true); 1121 } 1122 1123 if (update) 1124 lease_update_assignments(l_old); 1125 1126 free_lease(l_new); 1127 } 1128 1129 static void lease_delete(struct lease *l) 1130 { 1131 struct dhcp_assignment *a, *tmp; 1132 1133 list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) 1134 free_assignment(a); 1135 1136 free_lease(l); 1137 } 1138 1139 static void lease_update(_unused struct vlist_tree *tree, struct vlist_node *node_new, 1140 struct vlist_node *node_old) 1141 { 1142 struct lease *lease_new = container_of(node_new, struct lease, node); 1143 struct lease *lease_old = container_of(node_old, struct lease, node); 1144 1145 if (node_old && node_new) 1146 lease_change_config(lease_old, lease_new); 1147 else if (node_old) 1148 lease_delete(lease_old); 1149 } 1150 1151 struct lease *config_find_lease_by_duid(const uint8_t *duid, const uint16_t len) 1152 { 1153 struct lease *l; 1154 1155 vlist_for_each_element(&leases, l, node) { 1156 if (l->duid_len == len && !memcmp(l->duid, duid, len)) 1157 return l; 1158 } 1159 1160 return NULL; 1161 } 1162 1163 struct lease *config_find_lease_by_mac(const uint8_t *mac) 1164 { 1165 struct lease *l; 1166 1167 vlist_for_each_element(&leases, l, node) { 1168 if (!memcmp(l->mac.ether_addr_octet, mac, 1169 sizeof(l->mac.ether_addr_octet))) 1170 return l; 1171 } 1172 1173 return NULL; 1174 } 1175 1176 struct lease *config_find_lease_by_hostid(const uint64_t hostid) 1177 { 1178 struct lease *l; 1179 1180 vlist_for_each_element(&leases, l, node) { 1181 if (l->hostid == hostid) 1182 return l; 1183 } 1184 1185 return NULL; 1186 } 1187 1188 struct lease *config_find_lease_by_ipaddr(const uint32_t ipaddr) 1189 { 1190 struct lease *l; 1191 1192 vlist_for_each_element(&leases, l, node) { 1193 if (l->ipaddr == ipaddr) 1194 return l; 1195 } 1196 1197 return NULL; 1198 } 1199 1200 void odhcpd_reload(void) 1201 { 1202 struct uci_context *uci = uci_alloc_context(); 1203 struct interface *master = NULL, *i, *tmp; 1204 1205 if (!uci) 1206 return; 1207 1208 vlist_update(&leases); 1209 avl_for_each_element(&interfaces, i, avl) 1210 clean_interface(i); 1211 1212 struct uci_package *dhcp = NULL; 1213 if (!uci_load(uci, "dhcp", &dhcp)) { 1214 struct uci_element *e; 1215 1216 /* 1. Global settings */ 1217 uci_foreach_element(&dhcp->sections, e) { 1218 struct uci_section *s = uci_to_section(e); 1219 if (!strcmp(s->type, "odhcpd")) 1220 set_config(s); 1221 } 1222 1223 /* 2. DHCP pools */ 1224 uci_foreach_element(&dhcp->sections, e) { 1225 struct uci_section *s = uci_to_section(e); 1226 if (!strcmp(s->type, "dhcp")) 1227 set_interface(s); 1228 } 1229 1230 /* 3. Static leases */ 1231 uci_foreach_element(&dhcp->sections, e) { 1232 struct uci_section* s = uci_to_section(e); 1233 if (!strcmp(s->type, "host")) 1234 set_lease_from_uci(s); 1235 } 1236 } 1237 1238 if (config.dhcp_statefile) { 1239 char *path = strdup(config.dhcp_statefile); 1240 1241 mkdir_p(dirname(path), 0755); 1242 free(path); 1243 } 1244 1245 vlist_flush(&leases); 1246 1247 #ifdef WITH_UBUS 1248 ubus_apply_network(); 1249 #endif 1250 1251 bool any_dhcpv6_slave = false, any_ra_slave = false, any_ndp_slave = false; 1252 1253 /* Test for */ 1254 avl_for_each_element(&interfaces, i, avl) { 1255 if (i->master) 1256 continue; 1257 1258 if (i->dhcpv6 == MODE_HYBRID || i->dhcpv6 == MODE_RELAY) 1259 any_dhcpv6_slave = true; 1260 1261 if (i->ra == MODE_HYBRID || i->ra == MODE_RELAY) 1262 any_ra_slave = true; 1263 1264 if (i->ndp == MODE_HYBRID || i->ndp == MODE_RELAY) 1265 any_ndp_slave = true; 1266 } 1267 1268 /* Evaluate hybrid mode for master */ 1269 avl_for_each_element(&interfaces, i, avl) { 1270 if (!i->master) 1271 continue; 1272 1273 enum odhcpd_mode hybrid_mode = MODE_DISABLED; 1274 #ifdef WITH_UBUS 1275 if (!ubus_has_prefix(i->name, i->ifname)) 1276 hybrid_mode = MODE_RELAY; 1277 #endif 1278 1279 if (i->dhcpv6 == MODE_HYBRID) 1280 i->dhcpv6 = hybrid_mode; 1281 1282 if (i->dhcpv6 == MODE_RELAY && !any_dhcpv6_slave) 1283 i->dhcpv6 = MODE_DISABLED; 1284 1285 if (i->ra == MODE_HYBRID) 1286 i->ra = hybrid_mode; 1287 1288 if (i->ra == MODE_RELAY && !any_ra_slave) 1289 i->ra = MODE_DISABLED; 1290 1291 if (i->ndp == MODE_HYBRID) 1292 i->ndp = hybrid_mode; 1293 1294 if (i->ndp == MODE_RELAY && !any_ndp_slave) 1295 i->ndp = MODE_DISABLED; 1296 1297 if (i->dhcpv6 == MODE_RELAY || i->ra == MODE_RELAY || i->ndp == MODE_RELAY) 1298 master = i; 1299 } 1300 1301 1302 avl_for_each_element_safe(&interfaces, i, avl, tmp) { 1303 if (i->inuse) { 1304 /* Resolve hybrid mode */ 1305 if (i->dhcpv6 == MODE_HYBRID) 1306 i->dhcpv6 = (master && master->dhcpv6 == MODE_RELAY) ? 1307 MODE_RELAY : MODE_SERVER; 1308 1309 if (i->ra == MODE_HYBRID) 1310 i->ra = (master && master->ra == MODE_RELAY) ? 1311 MODE_RELAY : MODE_SERVER; 1312 1313 if (i->ndp == MODE_HYBRID) 1314 i->ndp = (master && master->ndp == MODE_RELAY) ? 1315 MODE_RELAY : MODE_DISABLED; 1316 1317 router_setup_interface(i, i->ra != MODE_DISABLED); 1318 dhcpv6_setup_interface(i, i->dhcpv6 != MODE_DISABLED); 1319 ndp_setup_interface(i, i->ndp != MODE_DISABLED); 1320 #ifdef DHCPV4_SUPPORT 1321 dhcpv4_setup_interface(i, i->dhcpv4 != MODE_DISABLED); 1322 #endif 1323 } else 1324 close_interface(i); 1325 } 1326 1327 uci_unload(uci, dhcp); 1328 uci_free_context(uci); 1329 } 1330 1331 static void handle_signal(int signal) 1332 { 1333 char b[1] = {0}; 1334 1335 if (signal == SIGHUP) { 1336 if (write(reload_pipe[1], b, sizeof(b)) < 0) {} 1337 } else 1338 uloop_end(); 1339 } 1340 1341 static void reload_cb(struct uloop_fd *u, _unused unsigned int events) 1342 { 1343 char b[512]; 1344 if (read(u->fd, b, sizeof(b)) < 0) {} 1345 1346 odhcpd_reload(); 1347 } 1348 1349 static struct uloop_fd reload_fd = { .fd = -1, .cb = reload_cb }; 1350 1351 void odhcpd_run(void) 1352 { 1353 if (pipe2(reload_pipe, O_NONBLOCK | O_CLOEXEC) < 0) {} 1354 1355 reload_fd.fd = reload_pipe[0]; 1356 uloop_fd_add(&reload_fd, ULOOP_READ); 1357 1358 signal(SIGTERM, handle_signal); 1359 signal(SIGINT, handle_signal); 1360 signal(SIGHUP, handle_signal); 1361 1362 #ifdef WITH_UBUS 1363 while (ubus_init()) 1364 sleep(1); 1365 #endif 1366 1367 odhcpd_reload(); 1368 uloop_run(); 1369 } 1370
This page was automatically generated by LXR 0.3.1. • OpenWrt