1 /* 2 * netifd - network interface daemon 3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 #include <string.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <assert.h> 18 19 #include <sys/types.h> 20 #include <sys/socket.h> 21 22 #include <libubox/list.h> 23 24 #include "netifd.h" 25 #include "system.h" 26 #include "config.h" 27 #include "wireless.h" 28 #include "ubus.h" 29 30 static struct list_head devtypes = LIST_HEAD_INIT(devtypes); 31 static struct avl_tree devices; 32 static struct blob_buf b; 33 34 static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = { 35 [DEV_ATTR_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }, 36 [DEV_ATTR_MTU] = { .name = "mtu", .type = BLOBMSG_TYPE_INT32 }, 37 [DEV_ATTR_MTU6] = { .name = "mtu6", .type = BLOBMSG_TYPE_INT32 }, 38 [DEV_ATTR_MACADDR] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING }, 39 [DEV_ATTR_TXQUEUELEN] = { .name = "txqueuelen", .type = BLOBMSG_TYPE_INT32 }, 40 [DEV_ATTR_ENABLED] = { .name = "enabled", .type = BLOBMSG_TYPE_BOOL }, 41 [DEV_ATTR_IPV6] = { .name = "ipv6", .type = BLOBMSG_TYPE_BOOL }, 42 [DEV_ATTR_IP6SEGMENTROUTING] = { .name = "ip6segmentrouting", .type = BLOBMSG_TYPE_BOOL }, 43 [DEV_ATTR_PROMISC] = { .name = "promisc", .type = BLOBMSG_TYPE_BOOL }, 44 [DEV_ATTR_RPFILTER] = { .name = "rpfilter", .type = BLOBMSG_TYPE_STRING }, 45 [DEV_ATTR_ACCEPTLOCAL] = { .name = "acceptlocal", .type = BLOBMSG_TYPE_BOOL }, 46 [DEV_ATTR_IGMPVERSION] = { .name = "igmpversion", .type = BLOBMSG_TYPE_INT32 }, 47 [DEV_ATTR_MLDVERSION] = { .name = "mldversion", .type = BLOBMSG_TYPE_INT32 }, 48 [DEV_ATTR_NEIGHREACHABLETIME] = { .name = "neighreachabletime", .type = BLOBMSG_TYPE_INT32 }, 49 [DEV_ATTR_NEIGHGCSTALETIME] = { .name = "neighgcstaletime", .type = BLOBMSG_TYPE_INT32 }, 50 [DEV_ATTR_DADTRANSMITS] = { .name = "dadtransmits", .type = BLOBMSG_TYPE_INT32 }, 51 [DEV_ATTR_MULTICAST_TO_UNICAST] = { .name = "multicast_to_unicast", .type = BLOBMSG_TYPE_BOOL }, 52 [DEV_ATTR_MULTICAST_ROUTER] = { .name = "multicast_router", .type = BLOBMSG_TYPE_INT32 }, 53 [DEV_ATTR_MULTICAST_FAST_LEAVE] = { .name = "multicast_fast_leave", . type = BLOBMSG_TYPE_BOOL }, 54 [DEV_ATTR_MULTICAST] = { .name ="multicast", .type = BLOBMSG_TYPE_BOOL }, 55 [DEV_ATTR_LEARNING] = { .name ="learning", .type = BLOBMSG_TYPE_BOOL }, 56 [DEV_ATTR_UNICAST_FLOOD] = { .name ="unicast_flood", .type = BLOBMSG_TYPE_BOOL }, 57 [DEV_ATTR_SENDREDIRECTS] = { .name = "sendredirects", .type = BLOBMSG_TYPE_BOOL }, 58 [DEV_ATTR_NEIGHLOCKTIME] = { .name = "neighlocktime", .type = BLOBMSG_TYPE_INT32 }, 59 [DEV_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL }, 60 [DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST] = { .name = "drop_v4_unicast_in_l2_multicast", .type = BLOBMSG_TYPE_BOOL }, 61 [DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST] = { .name = "drop_v6_unicast_in_l2_multicast", .type = BLOBMSG_TYPE_BOOL }, 62 [DEV_ATTR_DROP_GRATUITOUS_ARP] = { .name = "drop_gratuitous_arp", .type = BLOBMSG_TYPE_BOOL }, 63 [DEV_ATTR_DROP_UNSOLICITED_NA] = { .name = "drop_unsolicited_na", .type = BLOBMSG_TYPE_BOOL }, 64 [DEV_ATTR_ARP_ACCEPT] = { .name = "arp_accept", .type = BLOBMSG_TYPE_BOOL }, 65 [DEV_ATTR_AUTH] = { .name = "auth", .type = BLOBMSG_TYPE_BOOL }, 66 [DEV_ATTR_AUTH_VLAN] = { .name = "auth_vlan", BLOBMSG_TYPE_ARRAY }, 67 [DEV_ATTR_SPEED] = { .name = "speed", .type = BLOBMSG_TYPE_INT32 }, 68 [DEV_ATTR_DUPLEX] = { .name = "duplex", .type = BLOBMSG_TYPE_BOOL }, 69 [DEV_ATTR_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_ARRAY }, 70 [DEV_ATTR_PAUSE] = { .name = "pause", .type = BLOBMSG_TYPE_BOOL }, 71 [DEV_ATTR_ASYM_PAUSE] = { .name = "asym_pause", .type = BLOBMSG_TYPE_BOOL }, 72 [DEV_ATTR_RXPAUSE] = { .name = "rxpause", .type = BLOBMSG_TYPE_BOOL }, 73 [DEV_ATTR_TXPAUSE] = { .name = "txpause", .type = BLOBMSG_TYPE_BOOL }, 74 [DEV_ATTR_AUTONEG] = { .name = "autoneg", .type = BLOBMSG_TYPE_BOOL }, 75 [DEV_ATTR_GRO] = { .name = "gro", .type = BLOBMSG_TYPE_BOOL }, 76 [DEV_ATTR_MASTER] = { .name = "conduit", .type = BLOBMSG_TYPE_STRING }, 77 [DEV_ATTR_EEE] = { .name = "eee", .type = BLOBMSG_TYPE_BOOL }, 78 }; 79 80 const struct uci_blob_param_list device_attr_list = { 81 .n_params = __DEV_ATTR_MAX, 82 .params = dev_attrs, 83 }; 84 85 static int __devlock = 0; 86 87 int device_type_add(struct device_type *devtype) 88 { 89 if (device_type_get(devtype->name)) { 90 netifd_log_message(L_WARNING, "Device handler '%s' already exists\n", 91 devtype->name); 92 return 1; 93 } 94 95 netifd_log_message(L_NOTICE, "Added device handler type: %s\n", 96 devtype->name); 97 98 list_add(&devtype->list, &devtypes); 99 return 0; 100 } 101 102 struct device_type * 103 device_type_get(const char *tname) 104 { 105 struct device_type *cur; 106 107 list_for_each_entry(cur, &devtypes, list) 108 if (!strcmp(cur->name, tname)) 109 return cur; 110 111 return NULL; 112 } 113 114 static int device_vlan_len(struct kvlist *kv, const void *data) 115 { 116 return sizeof(unsigned int); 117 } 118 119 void device_vlan_update(bool done) 120 { 121 struct device *dev; 122 123 avl_for_each_element(&devices, dev, avl) { 124 if (!dev->vlans.update) 125 continue; 126 127 if (!done) { 128 if (dev->vlan_aliases.get_len) 129 kvlist_free(&dev->vlan_aliases); 130 else 131 kvlist_init(&dev->vlan_aliases, device_vlan_len); 132 vlist_update(&dev->vlans); 133 } else { 134 vlist_flush(&dev->vlans); 135 136 if (dev->type->vlan_update) 137 dev->type->vlan_update(dev); 138 } 139 } 140 } 141 142 void device_stp_init(void) 143 { 144 struct device *dev; 145 146 avl_for_each_element(&devices, dev, avl) { 147 if (!dev->type->stp_init) 148 continue; 149 150 dev->type->stp_init(dev); 151 } 152 } 153 154 static int set_device_state(struct device *dev, bool state) 155 { 156 if (state) { 157 /* Get ifindex for all devices being enabled so a valid */ 158 /* ifindex is in place avoiding possible race conditions */ 159 device_set_ifindex(dev, system_if_resolve(dev)); 160 if (!dev->ifindex) 161 return -1; 162 163 system_if_get_settings(dev, &dev->orig_settings); 164 /* Only keep orig settings based on what needs to be set */ 165 dev->orig_settings.valid_flags = dev->orig_settings.flags; 166 dev->orig_settings.flags &= dev->settings.flags; 167 system_if_apply_settings(dev, &dev->settings, dev->settings.flags); 168 169 system_if_up(dev); 170 171 system_if_apply_settings_after_up(dev, &dev->settings); 172 } else { 173 system_if_down(dev); 174 system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags); 175 } 176 177 return 0; 178 } 179 180 static int 181 simple_device_set_state(struct device *dev, bool state) 182 { 183 struct device *pdev; 184 int ret = 0; 185 186 pdev = dev->parent.dev; 187 if (state && !pdev) { 188 pdev = system_if_get_parent(dev); 189 if (pdev) 190 device_add_user(&dev->parent, pdev); 191 } 192 193 if (pdev) { 194 if (state) 195 ret = device_claim(&dev->parent); 196 else 197 device_release(&dev->parent); 198 199 if (ret < 0) 200 return ret; 201 } 202 return set_device_state(dev, state); 203 } 204 205 static struct device * 206 simple_device_create(const char *name, struct device_type *devtype, 207 struct blob_attr *attr) 208 { 209 struct blob_attr *tb[__DEV_ATTR_MAX]; 210 struct device *dev = NULL; 211 212 /* device type is unused for simple devices */ 213 devtype = NULL; 214 215 blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb, blob_data(attr), blob_len(attr)); 216 dev = device_get(name, true); 217 if (!dev) 218 return NULL; 219 220 dev->set_state = simple_device_set_state; 221 device_init_settings(dev, tb); 222 223 return dev; 224 } 225 226 static void simple_device_free(struct device *dev) 227 { 228 if (dev->parent.dev) 229 device_remove_user(&dev->parent); 230 free(dev); 231 } 232 233 struct device_type simple_device_type = { 234 .name = "Network device", 235 .config_params = &device_attr_list, 236 237 .create = simple_device_create, 238 .check_state = system_if_check, 239 .free = simple_device_free, 240 }; 241 242 void 243 device_merge_settings(struct device *dev, struct device_settings *n) 244 { 245 struct device_settings *os = &dev->orig_settings; 246 struct device_settings *s = &dev->settings; 247 248 memset(n, 0, sizeof(*n)); 249 n->mtu = s->flags & DEV_OPT_MTU ? s->mtu : os->mtu; 250 n->mtu6 = s->flags & DEV_OPT_MTU6 ? s->mtu6 : os->mtu6; 251 n->txqueuelen = s->flags & DEV_OPT_TXQUEUELEN ? 252 s->txqueuelen : os->txqueuelen; 253 memcpy(n->macaddr, 254 (s->flags & (DEV_OPT_MACADDR|DEV_OPT_DEFAULT_MACADDR) ? s->macaddr : os->macaddr), 255 sizeof(n->macaddr)); 256 n->ipv6 = s->flags & DEV_OPT_IPV6 ? s->ipv6 : os->ipv6; 257 n->ip6segmentrouting = s->flags & DEV_OPT_IP6SEGMENTROUTING ? s->ip6segmentrouting : os->ip6segmentrouting; 258 n->promisc = s->flags & DEV_OPT_PROMISC ? s->promisc : os->promisc; 259 n->rpfilter = s->flags & DEV_OPT_RPFILTER ? s->rpfilter : os->rpfilter; 260 n->acceptlocal = s->flags & DEV_OPT_ACCEPTLOCAL ? s->acceptlocal : os->acceptlocal; 261 n->igmpversion = s->flags & DEV_OPT_IGMPVERSION ? s->igmpversion : os->igmpversion; 262 n->mldversion = s->flags & DEV_OPT_MLDVERSION ? s->mldversion : os->mldversion; 263 n->neigh4reachabletime = s->flags & DEV_OPT_NEIGHREACHABLETIME ? 264 s->neigh4reachabletime : os->neigh4reachabletime; 265 n->neigh6reachabletime = s->flags & DEV_OPT_NEIGHREACHABLETIME ? 266 s->neigh6reachabletime : os->neigh6reachabletime; 267 n->neigh4gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ? 268 s->neigh4gcstaletime : os->neigh4gcstaletime; 269 n->neigh6gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ? 270 s->neigh6gcstaletime : os->neigh6gcstaletime; 271 n->neigh4locktime = s->flags & DEV_OPT_NEIGHLOCKTIME ? 272 s->neigh4locktime : os->neigh4locktime; 273 n->dadtransmits = s->flags & DEV_OPT_DADTRANSMITS ? 274 s->dadtransmits : os->dadtransmits; 275 n->multicast = s->flags & DEV_OPT_MULTICAST ? 276 s->multicast : os->multicast; 277 n->multicast_to_unicast = s->multicast_to_unicast; 278 n->multicast_router = s->multicast_router; 279 n->multicast_fast_leave = s->multicast_fast_leave; 280 n->learning = s->learning; 281 n->unicast_flood = s->unicast_flood; 282 n->sendredirects = s->flags & DEV_OPT_SENDREDIRECTS ? 283 s->sendredirects : os->sendredirects; 284 n->drop_v4_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST ? 285 s->drop_v4_unicast_in_l2_multicast : os->drop_v4_unicast_in_l2_multicast; 286 n->drop_v6_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST ? 287 s->drop_v6_unicast_in_l2_multicast : os->drop_v6_unicast_in_l2_multicast; 288 n->drop_gratuitous_arp = s->flags & DEV_OPT_DROP_GRATUITOUS_ARP ? 289 s->drop_gratuitous_arp : os->drop_gratuitous_arp; 290 n->drop_unsolicited_na = s->flags & DEV_OPT_DROP_UNSOLICITED_NA ? 291 s->drop_unsolicited_na : os->drop_unsolicited_na; 292 n->arp_accept = s->flags & DEV_OPT_ARP_ACCEPT ? 293 s->arp_accept : os->arp_accept; 294 n->auth = s->flags & DEV_OPT_AUTH ? s->auth : os->auth; 295 n->speed = s->flags & DEV_OPT_SPEED ? s->speed : os->speed; 296 n->duplex = s->flags & DEV_OPT_DUPLEX ? s->duplex : os->duplex; 297 n->pause = s->flags & DEV_OPT_PAUSE ? s->pause : os->pause; 298 n->asym_pause = s->flags & DEV_OPT_ASYM_PAUSE ? s->asym_pause : os->asym_pause; 299 n->rxpause = s->flags & DEV_OPT_RXPAUSE ? s->rxpause : os->rxpause; 300 n->txpause = s->flags & DEV_OPT_TXPAUSE ? s->txpause : os->txpause; 301 n->autoneg = s->flags & DEV_OPT_AUTONEG ? s->autoneg : os->autoneg; 302 n->gro = s->flags & DEV_OPT_GRO ? s->gro : os->gro; 303 n->eee = s->flags & DEV_OPT_EEE ? s->eee : os->eee; 304 n->master_ifindex = s->flags & DEV_OPT_MASTER ? s->master_ifindex : os->master_ifindex; 305 n->flags = s->flags | os->flags | os->valid_flags; 306 } 307 308 static bool device_fill_vlan_range(struct device_vlan_range *r, const char *val) 309 { 310 unsigned long cur_start, cur_end; 311 char *sep; 312 313 cur_start = strtoul(val, &sep, 0); 314 cur_end = cur_start; 315 316 if (*sep == '-') 317 cur_end = strtoul(sep + 1, &sep, 0); 318 if (*sep || cur_end < cur_start) 319 return false; 320 321 r->start = cur_start; 322 r->end = cur_end; 323 324 return true; 325 } 326 327 static void 328 device_set_extra_vlans(struct device *dev, struct blob_attr *data) 329 { 330 struct blob_attr *cur; 331 int n_vlans; 332 size_t rem; 333 334 dev->n_extra_vlan = 0; 335 if (!data) 336 return; 337 338 n_vlans = blobmsg_check_array(data, BLOBMSG_TYPE_STRING); 339 if (n_vlans < 1) 340 return; 341 342 dev->extra_vlan = realloc(dev->extra_vlan, n_vlans * sizeof(*dev->extra_vlan)); 343 blobmsg_for_each_attr(cur, data, rem) 344 if (device_fill_vlan_range(&dev->extra_vlan[dev->n_extra_vlan], 345 blobmsg_get_string(cur))) 346 dev->n_extra_vlan++; 347 } 348 349 void 350 device_init_settings(struct device *dev, struct blob_attr **tb) 351 { 352 struct device_settings *s = &dev->settings; 353 struct blob_attr *cur; 354 struct ether_addr *ea; 355 bool disabled = false; 356 357 if (dev->wireless) 358 s->flags &= DEV_OPT_ISOLATE; 359 else 360 s->flags = 0; 361 if ((cur = tb[DEV_ATTR_ENABLED])) 362 disabled = !blobmsg_get_bool(cur); 363 364 if ((cur = tb[DEV_ATTR_MTU]) && blobmsg_get_u32(cur) >= 68) { 365 s->mtu = blobmsg_get_u32(cur); 366 s->flags |= DEV_OPT_MTU; 367 } 368 369 if ((cur = tb[DEV_ATTR_MTU6]) && blobmsg_get_u32(cur) >= 1280) { 370 s->mtu6 = blobmsg_get_u32(cur); 371 s->flags |= DEV_OPT_MTU6; 372 } 373 374 if ((cur = tb[DEV_ATTR_TXQUEUELEN])) { 375 s->txqueuelen = blobmsg_get_u32(cur); 376 s->flags |= DEV_OPT_TXQUEUELEN; 377 } 378 379 if ((cur = tb[DEV_ATTR_MACADDR])) { 380 ea = ether_aton(blobmsg_data(cur)); 381 if (ea) { 382 memcpy(s->macaddr, ea, 6); 383 s->flags |= DEV_OPT_MACADDR; 384 } 385 } 386 387 if ((cur = tb[DEV_ATTR_IPV6])) { 388 s->ipv6 = blobmsg_get_bool(cur); 389 s->flags |= DEV_OPT_IPV6; 390 } 391 392 if ((cur = tb[DEV_ATTR_IP6SEGMENTROUTING])) { 393 s->ip6segmentrouting = blobmsg_get_bool(cur); 394 s->flags |= DEV_OPT_IP6SEGMENTROUTING; 395 } 396 397 if ((cur = tb[DEV_ATTR_PROMISC])) { 398 s->promisc = blobmsg_get_bool(cur); 399 s->flags |= DEV_OPT_PROMISC; 400 } 401 402 if ((cur = tb[DEV_ATTR_RPFILTER])) { 403 if (system_resolve_rpfilter(blobmsg_data(cur), &s->rpfilter)) 404 s->flags |= DEV_OPT_RPFILTER; 405 else 406 D(DEVICE, "Failed to resolve rpfilter: %s\n", (char *) blobmsg_data(cur)); 407 } 408 409 if ((cur = tb[DEV_ATTR_ACCEPTLOCAL])) { 410 s->acceptlocal = blobmsg_get_bool(cur); 411 s->flags |= DEV_OPT_ACCEPTLOCAL; 412 } 413 414 if ((cur = tb[DEV_ATTR_IGMPVERSION])) { 415 s->igmpversion = blobmsg_get_u32(cur); 416 if (s->igmpversion >= 1 && s->igmpversion <= 3) 417 s->flags |= DEV_OPT_IGMPVERSION; 418 else 419 D(DEVICE, "Failed to resolve igmpversion: %d\n", blobmsg_get_u32(cur)); 420 } 421 422 if ((cur = tb[DEV_ATTR_MLDVERSION])) { 423 s->mldversion = blobmsg_get_u32(cur); 424 if (s->mldversion >= 1 && s->mldversion <= 2) 425 s->flags |= DEV_OPT_MLDVERSION; 426 else 427 D(DEVICE, "Failed to resolve mldversion: %d\n", blobmsg_get_u32(cur)); 428 } 429 430 if ((cur = tb[DEV_ATTR_NEIGHREACHABLETIME])) { 431 s->neigh6reachabletime = s->neigh4reachabletime = blobmsg_get_u32(cur); 432 s->flags |= DEV_OPT_NEIGHREACHABLETIME; 433 } 434 435 if ((cur = tb[DEV_ATTR_NEIGHGCSTALETIME])) { 436 s->neigh6gcstaletime = s->neigh4gcstaletime = blobmsg_get_u32(cur); 437 s->flags |= DEV_OPT_NEIGHGCSTALETIME; 438 } 439 440 if ((cur = tb[DEV_ATTR_NEIGHLOCKTIME])) { 441 s->neigh4locktime = blobmsg_get_u32(cur); 442 s->flags |= DEV_OPT_NEIGHLOCKTIME; 443 } 444 445 if ((cur = tb[DEV_ATTR_DADTRANSMITS])) { 446 s->dadtransmits = blobmsg_get_u32(cur); 447 s->flags |= DEV_OPT_DADTRANSMITS; 448 } 449 450 if ((cur = tb[DEV_ATTR_MULTICAST_TO_UNICAST])) { 451 s->multicast_to_unicast = blobmsg_get_bool(cur); 452 s->flags |= DEV_OPT_MULTICAST_TO_UNICAST; 453 } 454 455 if ((cur = tb[DEV_ATTR_MULTICAST_ROUTER])) { 456 s->multicast_router = blobmsg_get_u32(cur); 457 if (s->multicast_router <= 2) 458 s->flags |= DEV_OPT_MULTICAST_ROUTER; 459 else 460 D(DEVICE, "Invalid value: %d - (Use 0: never, 1: learn, 2: always)\n", blobmsg_get_u32(cur)); 461 } 462 463 if ((cur = tb[DEV_ATTR_MULTICAST_FAST_LEAVE])) { 464 s->multicast_fast_leave = blobmsg_get_bool(cur); 465 s->flags |= DEV_OPT_MULTICAST_FAST_LEAVE; 466 } 467 468 if ((cur = tb[DEV_ATTR_MULTICAST])) { 469 s->multicast = blobmsg_get_bool(cur); 470 s->flags |= DEV_OPT_MULTICAST; 471 } 472 473 if ((cur = tb[DEV_ATTR_LEARNING])) { 474 s->learning = blobmsg_get_bool(cur); 475 s->flags |= DEV_OPT_LEARNING; 476 } 477 478 if ((cur = tb[DEV_ATTR_UNICAST_FLOOD])) { 479 s->unicast_flood = blobmsg_get_bool(cur); 480 s->flags |= DEV_OPT_UNICAST_FLOOD; 481 } 482 483 if ((cur = tb[DEV_ATTR_SENDREDIRECTS])) { 484 s->sendredirects = blobmsg_get_bool(cur); 485 s->flags |= DEV_OPT_SENDREDIRECTS; 486 } 487 488 if ((cur = tb[DEV_ATTR_ISOLATE])) { 489 s->isolate = blobmsg_get_bool(cur); 490 s->flags |= DEV_OPT_ISOLATE; 491 } 492 493 if ((cur = tb[DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST])) { 494 s->drop_v4_unicast_in_l2_multicast = blobmsg_get_bool(cur); 495 s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST; 496 } 497 498 if ((cur = tb[DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST])) { 499 s->drop_v6_unicast_in_l2_multicast = blobmsg_get_bool(cur); 500 s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST; 501 } 502 503 if ((cur = tb[DEV_ATTR_DROP_GRATUITOUS_ARP])) { 504 s->drop_gratuitous_arp = blobmsg_get_bool(cur); 505 s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP; 506 } 507 508 if ((cur = tb[DEV_ATTR_DROP_UNSOLICITED_NA])) { 509 s->drop_unsolicited_na = blobmsg_get_bool(cur); 510 s->flags |= DEV_OPT_DROP_UNSOLICITED_NA; 511 } 512 513 if ((cur = tb[DEV_ATTR_ARP_ACCEPT])) { 514 s->arp_accept = blobmsg_get_bool(cur); 515 s->flags |= DEV_OPT_ARP_ACCEPT; 516 } 517 518 if ((cur = tb[DEV_ATTR_AUTH])) { 519 s->auth = blobmsg_get_bool(cur); 520 s->flags |= DEV_OPT_AUTH; 521 } 522 523 if ((cur = tb[DEV_ATTR_SPEED])) { 524 s->speed = blobmsg_get_u32(cur); 525 s->flags |= DEV_OPT_SPEED; 526 } 527 528 if ((cur = tb[DEV_ATTR_DUPLEX])) { 529 s->duplex = blobmsg_get_bool(cur); 530 s->flags |= DEV_OPT_DUPLEX; 531 } 532 533 if ((cur = tb[DEV_ATTR_PAUSE])) { 534 s->pause = blobmsg_get_bool(cur); 535 s->flags |= DEV_OPT_PAUSE; 536 } 537 538 if ((cur = tb[DEV_ATTR_ASYM_PAUSE])) { 539 s->asym_pause = blobmsg_get_bool(cur); 540 s->flags |= DEV_OPT_ASYM_PAUSE; 541 } 542 543 if ((cur = tb[DEV_ATTR_RXPAUSE])) { 544 s->rxpause = blobmsg_get_bool(cur); 545 s->flags |= DEV_OPT_RXPAUSE; 546 } 547 548 if ((cur = tb[DEV_ATTR_TXPAUSE])) { 549 s->txpause = blobmsg_get_bool(cur); 550 s->flags |= DEV_OPT_TXPAUSE; 551 } 552 553 if ((cur = tb[DEV_ATTR_AUTONEG])) { 554 s->autoneg = blobmsg_get_bool(cur); 555 s->flags |= DEV_OPT_AUTONEG; 556 } 557 558 if ((cur = tb[DEV_ATTR_GRO])) { 559 s->gro = blobmsg_get_bool(cur); 560 s->flags |= DEV_OPT_GRO; 561 } 562 563 if ((cur = tb[DEV_ATTR_MASTER])) { 564 char *ifname = blobmsg_get_string(cur); 565 s->master_ifindex = if_nametoindex(ifname); 566 s->flags |= DEV_OPT_MASTER; 567 } 568 569 if ((cur = tb[DEV_ATTR_EEE])) { 570 s->eee = blobmsg_get_bool(cur); 571 s->flags |= DEV_OPT_EEE; 572 } 573 574 cur = tb[DEV_ATTR_AUTH_VLAN]; 575 free(dev->config_auth_vlans); 576 dev->config_auth_vlans = cur ? blob_memdup(cur) : NULL; 577 578 device_set_extra_vlans(dev, tb[DEV_ATTR_VLAN]); 579 device_set_disabled(dev, disabled); 580 } 581 582 static void __init dev_init(void) 583 { 584 avl_init(&devices, avl_strcmp, true, NULL); 585 } 586 587 static int device_release_cb(void *ctx, struct safe_list *list) 588 { 589 struct device_user *dep = container_of(list, struct device_user, list); 590 591 if (!dep->dev || !dep->claimed) 592 return 0; 593 594 device_release(dep); 595 return 0; 596 } 597 598 static int device_broadcast_cb(void *ctx, struct safe_list *list) 599 { 600 struct device_user *dep = container_of(list, struct device_user, list); 601 int *ev = ctx; 602 603 /* device might have been removed by an earlier callback */ 604 if (!dep->dev) 605 return 0; 606 607 if (dep->cb) 608 dep->cb(dep, *ev); 609 return 0; 610 } 611 612 void device_broadcast_event(struct device *dev, enum device_event ev) 613 { 614 static const char * const event_names[] = { 615 [DEV_EVENT_ADD] = "add", 616 [DEV_EVENT_REMOVE] = "remove", 617 [DEV_EVENT_UP] = "up", 618 [DEV_EVENT_DOWN] = "down", 619 [DEV_EVENT_AUTH_UP] = "auth_up", 620 [DEV_EVENT_LINK_UP] = "link_up", 621 [DEV_EVENT_LINK_DOWN] = "link_down", 622 [DEV_EVENT_TOPO_CHANGE] = "topo_change", 623 }; 624 int dev_ev = ev; 625 626 safe_list_for_each(&dev->aliases, device_broadcast_cb, &dev_ev); 627 safe_list_for_each(&dev->users, device_broadcast_cb, &dev_ev); 628 629 if (ev >= ARRAY_SIZE(event_names) || !event_names[ev] || !dev->ifname[0]) 630 return; 631 632 blob_buf_init(&b, 0); 633 blobmsg_add_string(&b, "name", dev->ifname); 634 blobmsg_add_u8(&b, "auth_status", dev->auth_status); 635 blobmsg_add_u8(&b, "present", dev->present); 636 blobmsg_add_u8(&b, "active", dev->active); 637 blobmsg_add_u8(&b, "link_active", dev->link_active); 638 netifd_ubus_device_notify(event_names[ev], b.head, -1); 639 } 640 641 static void 642 device_fill_default_settings(struct device *dev) 643 { 644 struct device_settings *s = &dev->settings; 645 struct ether_addr *ea; 646 const char *master; 647 int ret; 648 649 if (!(s->flags & DEV_OPT_MACADDR)) { 650 ea = config_get_default_macaddr(dev->ifname); 651 if (ea) { 652 memcpy(s->macaddr, ea, 6); 653 s->flags |= DEV_OPT_DEFAULT_MACADDR; 654 } 655 } 656 657 if (!(s->flags & DEV_OPT_GRO)) { 658 ret = config_get_default_gro(dev->ifname); 659 if (ret >= 0) { 660 s->gro = ret; 661 s->flags |= DEV_OPT_GRO; 662 } 663 } 664 665 if (!(s->flags & DEV_OPT_MASTER)) { 666 master = config_get_default_conduit(dev->ifname); 667 if (master) { 668 s->master_ifindex = if_nametoindex(master); 669 s->flags |= DEV_OPT_MASTER; 670 } 671 } 672 } 673 674 int device_claim(struct device_user *dep) 675 { 676 struct device *dev = dep->dev; 677 int ret = 0; 678 679 if (dep->claimed) 680 return 0; 681 682 if (!dev) 683 return -1; 684 685 dep->claimed = true; 686 D(DEVICE, "Claim %s %s, new active count: %d\n", dev->type->name, dev->ifname, dev->active + 1); 687 if (++dev->active != 1) 688 return 0; 689 690 device_broadcast_event(dev, DEV_EVENT_SETUP); 691 device_fill_default_settings(dev); 692 if (dev->external) { 693 /* Get ifindex for external claimed devices so a valid */ 694 /* ifindex is in place avoiding possible race conditions */ 695 device_set_ifindex(dev, system_if_resolve(dev)); 696 if (!dev->ifindex) 697 ret = -1; 698 699 system_if_get_settings(dev, &dev->orig_settings); 700 } else 701 ret = dev->set_state(dev, true); 702 703 if (ret == 0) 704 device_broadcast_event(dev, DEV_EVENT_UP); 705 else { 706 D(DEVICE, "claim %s %s failed: %d\n", dev->type->name, dev->ifname, ret); 707 dev->active = 0; 708 dep->claimed = false; 709 } 710 711 return ret; 712 } 713 714 void device_release(struct device_user *dep) 715 { 716 struct device *dev = dep->dev; 717 718 if (!dep->claimed) 719 return; 720 721 dep->claimed = false; 722 dev->active--; 723 D(DEVICE, "Release %s %s, new active count: %d\n", dev->type->name, dev->ifname, dev->active); 724 assert(dev->active >= 0); 725 726 if (dev->active) 727 return; 728 729 device_broadcast_event(dev, DEV_EVENT_TEARDOWN); 730 if (!dev->external) 731 dev->set_state(dev, false); 732 733 if (dev->active) 734 return; 735 736 device_broadcast_event(dev, DEV_EVENT_DOWN); 737 } 738 739 int device_check_state(struct device *dev) 740 { 741 if (!dev->type->check_state) 742 return simple_device_type.check_state(dev); 743 744 return dev->type->check_state(dev); 745 } 746 747 int device_init_virtual(struct device *dev, struct device_type *type, const char *name) 748 { 749 assert(dev); 750 assert(type); 751 752 D(DEVICE, "Initialize device '%s'\n", name ? name : ""); 753 INIT_SAFE_LIST(&dev->users); 754 INIT_SAFE_LIST(&dev->aliases); 755 dev->type = type; 756 757 if (name) { 758 int ret; 759 760 ret = device_set_ifname(dev, name); 761 if (ret < 0) 762 return ret; 763 } 764 765 if (!dev->set_state) 766 dev->set_state = set_device_state; 767 768 return 0; 769 } 770 771 int device_init(struct device *dev, struct device_type *type, const char *ifname) 772 { 773 int ret; 774 775 ret = device_init_virtual(dev, type, ifname); 776 if (ret < 0) 777 return ret; 778 779 dev->avl.key = dev->ifname; 780 781 ret = avl_insert(&devices, &dev->avl); 782 if (ret < 0) 783 return ret; 784 785 system_if_clear_state(dev); 786 787 return 0; 788 } 789 790 static struct device * 791 device_create_default(const char *name, bool external) 792 { 793 struct device *dev; 794 795 if (!external && system_if_force_external(name)) 796 return NULL; 797 798 D(DEVICE, "Create simple device '%s'\n", name); 799 dev = calloc(1, sizeof(*dev)); 800 if (!dev) 801 return NULL; 802 803 dev->external = external; 804 dev->set_state = simple_device_set_state; 805 806 if (device_init(dev, &simple_device_type, name) < 0) { 807 device_cleanup(dev); 808 free(dev); 809 return NULL; 810 } 811 812 dev->default_config = true; 813 if (external) 814 system_if_apply_settings(dev, &dev->settings, dev->settings.flags); 815 816 device_check_state(dev); 817 818 return dev; 819 } 820 821 struct device * 822 device_find(const char *name) 823 { 824 struct device *dev; 825 826 return avl_find_element(&devices, name, dev, avl); 827 } 828 829 struct device * 830 __device_get(const char *name, int create, bool check_vlan) 831 { 832 struct device *dev; 833 834 dev = avl_find_element(&devices, name, dev, avl); 835 836 if (!dev && check_vlan && strchr(name, '.')) 837 return get_vlan_device_chain(name, create); 838 839 if (name[0] == '@') 840 return device_alias_get(name + 1); 841 842 if (dev) { 843 if (create > 1 && !dev->external) { 844 system_if_apply_settings(dev, &dev->settings, dev->settings.flags); 845 dev->external = true; 846 device_set_present(dev, true); 847 } 848 return dev; 849 } 850 851 if (!create) 852 return NULL; 853 854 return device_create_default(name, create > 1); 855 } 856 857 static void 858 device_delete(struct device *dev) 859 { 860 if (!dev->avl.key) 861 return; 862 863 D(DEVICE, "Delete device '%s' from list\n", dev->ifname); 864 avl_delete(&devices, &dev->avl); 865 dev->avl.key = NULL; 866 } 867 868 static int device_cleanup_cb(void *ctx, struct safe_list *list) 869 { 870 struct device_user *dep = container_of(list, struct device_user, list); 871 if (dep->cb) 872 dep->cb(dep, DEV_EVENT_REMOVE); 873 874 device_release(dep); 875 return 0; 876 } 877 878 void device_cleanup(struct device *dev) 879 { 880 D(DEVICE, "Clean up device '%s'\n", dev->ifname); 881 safe_list_for_each(&dev->users, device_cleanup_cb, NULL); 882 safe_list_for_each(&dev->aliases, device_cleanup_cb, NULL); 883 device_delete(dev); 884 } 885 886 static void __device_set_present(struct device *dev, bool state, bool force) 887 { 888 if (dev->present == state && !force) 889 return; 890 891 dev->present = state; 892 device_broadcast_event(dev, state ? DEV_EVENT_ADD : DEV_EVENT_REMOVE); 893 } 894 895 void 896 device_refresh_present(struct device *dev) 897 { 898 bool state = dev->sys_present; 899 900 if (dev->disabled || dev->deferred) 901 state = false; 902 903 __device_set_present(dev, state, false); 904 } 905 906 void 907 device_set_auth_status(struct device *dev, bool value, struct blob_attr *vlans) 908 { 909 if (!value) 910 vlans = NULL; 911 else if (!blob_attr_equal(vlans, dev->auth_vlans)) 912 device_set_auth_status(dev, false, NULL); 913 914 free(dev->auth_vlans); 915 dev->auth_vlans = vlans ? blob_memdup(vlans) : NULL; 916 917 if (dev->auth_status == value) 918 return; 919 920 dev->auth_status = value; 921 if (!dev->present) 922 return; 923 924 if (dev->auth_status) { 925 device_broadcast_event(dev, DEV_EVENT_AUTH_UP); 926 return; 927 } 928 929 device_broadcast_event(dev, DEV_EVENT_LINK_DOWN); 930 if (!dev->link_active) 931 return; 932 933 device_broadcast_event(dev, DEV_EVENT_LINK_UP); 934 } 935 936 void device_set_present(struct device *dev, bool state) 937 { 938 if (dev->sys_present == state) 939 return; 940 941 D(DEVICE, "%s '%s' %s present\n", dev->type->name, dev->ifname, state ? "is now" : "is no longer" ); 942 dev->sys_present = state; 943 if (!state) 944 __device_set_present(dev, state, true); 945 else 946 device_refresh_present(dev); 947 if (!state) 948 safe_list_for_each(&dev->users, device_release_cb, NULL); 949 } 950 951 void device_set_link(struct device *dev, bool state) 952 { 953 if (dev->link_active == state) 954 return; 955 956 netifd_log_message(L_NOTICE, "%s '%s' link is %s\n", dev->type->name, dev->ifname, state ? "up" : "down" ); 957 958 dev->link_active = state; 959 if (!state) 960 dev->auth_status = false; 961 device_broadcast_event(dev, state ? DEV_EVENT_LINK_UP : DEV_EVENT_LINK_DOWN); 962 } 963 964 void device_set_ifindex(struct device *dev, int ifindex) 965 { 966 if (dev->ifindex == ifindex) 967 return; 968 969 dev->ifindex = ifindex; 970 device_broadcast_event(dev, DEV_EVENT_UPDATE_IFINDEX); 971 } 972 973 int device_set_ifname(struct device *dev, const char *name) 974 { 975 int ret = 0; 976 977 if (!strcmp(dev->ifname, name)) 978 return 0; 979 980 if (strlen(name) > sizeof(dev->ifname) - 1) 981 return -1; 982 983 if (dev->avl.key) 984 avl_delete(&devices, &dev->avl); 985 986 strcpy(dev->ifname, name); 987 988 if (dev->avl.key) 989 ret = avl_insert(&devices, &dev->avl); 990 991 if (ret == 0) 992 device_broadcast_event(dev, DEV_EVENT_UPDATE_IFNAME); 993 994 return ret; 995 } 996 997 static int device_refcount(struct device *dev) 998 { 999 struct list_head *list; 1000 int count = 0; 1001 1002 list_for_each(list, &dev->users.list) 1003 count++; 1004 1005 list_for_each(list, &dev->aliases.list) 1006 count++; 1007 1008 return count; 1009 } 1010 1011 static void 1012 __device_add_user(struct device_user *dep, struct device *dev) 1013 { 1014 struct safe_list *head; 1015 1016 dep->dev = dev; 1017 1018 if (dep->alias) 1019 head = &dev->aliases; 1020 else 1021 head = &dev->users; 1022 1023 safe_list_add(&dep->list, head); 1024 D(DEVICE, "Add user for device '%s', refcount=%d\n", dev->ifname, device_refcount(dev)); 1025 1026 if (dep->cb && dev->present) { 1027 dep->cb(dep, DEV_EVENT_ADD); 1028 if (dev->active) 1029 dep->cb(dep, DEV_EVENT_UP); 1030 1031 if (dev->link_active) 1032 dep->cb(dep, DEV_EVENT_LINK_UP); 1033 } 1034 } 1035 1036 void device_add_user(struct device_user *dep, struct device *dev) 1037 { 1038 if (dep->dev == dev) 1039 return; 1040 1041 if (dep->dev) 1042 device_remove_user(dep); 1043 1044 if (!dev) 1045 return; 1046 1047 __device_add_user(dep, dev); 1048 } 1049 1050 static void 1051 device_free(struct device *dev) 1052 { 1053 __devlock++; 1054 free(dev->auth_vlans); 1055 free(dev->config); 1056 device_cleanup(dev); 1057 free(dev->config_auth_vlans); 1058 free(dev->extra_vlan); 1059 dev->type->free(dev); 1060 __devlock--; 1061 } 1062 1063 static void 1064 __device_free_unused(struct uloop_timeout *timeout) 1065 { 1066 struct device *dev, *tmp; 1067 1068 avl_for_each_element_safe(&devices, dev, avl, tmp) { 1069 if (!safe_list_empty(&dev->users) || 1070 !safe_list_empty(&dev->aliases) || 1071 dev->current_config) 1072 continue; 1073 1074 device_free(dev); 1075 } 1076 } 1077 1078 void device_free_unused(void) 1079 { 1080 static struct uloop_timeout free_timer = { 1081 .cb = __device_free_unused, 1082 }; 1083 1084 uloop_timeout_set(&free_timer, 1); 1085 } 1086 1087 void device_remove_user(struct device_user *dep) 1088 { 1089 struct device *dev = dep->dev; 1090 1091 if (!dep->dev) 1092 return; 1093 1094 dep->hotplug = false; 1095 if (dep->claimed) 1096 device_release(dep); 1097 1098 safe_list_del(&dep->list); 1099 dep->dev = NULL; 1100 D(DEVICE, "Remove user for device '%s', refcount=%d\n", dev->ifname, device_refcount(dev)); 1101 device_free_unused(); 1102 } 1103 1104 void 1105 device_init_pending(void) 1106 { 1107 struct device *dev, *tmp; 1108 1109 avl_for_each_element_safe(&devices, dev, avl, tmp) { 1110 if (!dev->config_pending) 1111 continue; 1112 1113 dev->type->config_init(dev); 1114 dev->config_pending = false; 1115 device_check_state(dev); 1116 } 1117 } 1118 1119 bool 1120 device_check_ip6segmentrouting(void) 1121 { 1122 struct device *dev; 1123 bool ip6segmentrouting = false; 1124 1125 avl_for_each_element(&devices, dev, avl) 1126 ip6segmentrouting |= dev->settings.ip6segmentrouting; 1127 1128 return ip6segmentrouting; 1129 } 1130 1131 static enum dev_change_type 1132 device_set_config(struct device *dev, struct device_type *type, 1133 struct blob_attr *attr) 1134 { 1135 struct blob_attr *tb[__DEV_ATTR_MAX]; 1136 const struct uci_blob_param_list *cfg = type->config_params; 1137 1138 if (type != dev->type) 1139 return DEV_CONFIG_RECREATE; 1140 1141 if (dev->type->reload) 1142 return dev->type->reload(dev, attr); 1143 1144 if (uci_blob_check_equal(dev->config, attr, cfg)) 1145 return DEV_CONFIG_NO_CHANGE; 1146 1147 if (cfg == &device_attr_list) { 1148 memset(tb, 0, sizeof(tb)); 1149 1150 if (attr) 1151 blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb, 1152 blob_data(attr), blob_len(attr)); 1153 1154 device_init_settings(dev, tb); 1155 return DEV_CONFIG_RESTART; 1156 } else 1157 return DEV_CONFIG_RECREATE; 1158 } 1159 1160 enum dev_change_type 1161 device_apply_config(struct device *dev, struct device_type *type, 1162 struct blob_attr *config) 1163 { 1164 enum dev_change_type change; 1165 1166 change = device_set_config(dev, type, config); 1167 if (dev->external) { 1168 system_if_apply_settings(dev, &dev->settings, dev->settings.flags); 1169 change = DEV_CONFIG_APPLIED; 1170 } 1171 1172 switch (change) { 1173 case DEV_CONFIG_RESTART: 1174 case DEV_CONFIG_APPLIED: 1175 D(DEVICE, "Device '%s': config applied\n", dev->ifname); 1176 config = blob_memdup(config); 1177 free(dev->config); 1178 dev->config = config; 1179 if (change == DEV_CONFIG_RESTART && dev->present) { 1180 int ret = 0; 1181 1182 device_set_present(dev, false); 1183 if (dev->active && !dev->external) { 1184 ret = dev->set_state(dev, false); 1185 if (!ret) 1186 ret = dev->set_state(dev, true); 1187 } 1188 if (!ret) 1189 device_set_present(dev, true); 1190 } 1191 break; 1192 case DEV_CONFIG_NO_CHANGE: 1193 D(DEVICE, "Device '%s': no configuration change\n", dev->ifname); 1194 break; 1195 case DEV_CONFIG_RECREATE: 1196 break; 1197 } 1198 1199 return change; 1200 } 1201 1202 static void 1203 device_replace(struct device *dev, struct device *odev) 1204 { 1205 struct device_user *dep; 1206 1207 __devlock++; 1208 if (odev->present) 1209 device_set_present(odev, false); 1210 1211 while (!list_empty(&odev->users.list)) { 1212 dep = list_first_entry(&odev->users.list, struct device_user, list.list); 1213 device_release(dep); 1214 if (!dep->dev) 1215 continue; 1216 1217 safe_list_del(&dep->list); 1218 __device_add_user(dep, dev); 1219 } 1220 __devlock--; 1221 1222 device_free(odev); 1223 } 1224 1225 void 1226 device_reset_config(void) 1227 { 1228 struct device *dev; 1229 1230 avl_for_each_element(&devices, dev, avl) 1231 dev->current_config = false; 1232 } 1233 1234 void 1235 device_reset_old(void) 1236 { 1237 struct device *dev, *tmp, *ndev; 1238 1239 avl_for_each_element_safe(&devices, dev, avl, tmp) { 1240 if (dev->current_config || dev->default_config) 1241 continue; 1242 1243 if (dev->type != &simple_device_type) 1244 continue; 1245 1246 ndev = device_create_default(dev->ifname, dev->external); 1247 if (!ndev) 1248 continue; 1249 1250 device_replace(ndev, dev); 1251 } 1252 } 1253 1254 struct device * 1255 device_create(const char *name, struct device_type *type, 1256 struct blob_attr *config) 1257 { 1258 struct device *odev = NULL, *dev; 1259 enum dev_change_type change; 1260 1261 odev = device_find(name); 1262 if (odev) { 1263 odev->current_config = true; 1264 change = device_apply_config(odev, type, config); 1265 switch (change) { 1266 case DEV_CONFIG_RECREATE: 1267 D(DEVICE, "Device '%s': recreate device\n", odev->ifname); 1268 device_delete(odev); 1269 break; 1270 default: 1271 return odev; 1272 } 1273 } else 1274 D(DEVICE, "Create new device '%s' (%s)\n", name, type->name); 1275 1276 config = blob_memdup(config); 1277 if (!config) 1278 return NULL; 1279 1280 dev = type->create(name, type, config); 1281 if (!dev) 1282 return NULL; 1283 1284 dev->current_config = true; 1285 dev->config = config; 1286 if (odev) 1287 device_replace(dev, odev); 1288 1289 if (!config_init && dev->config_pending) { 1290 type->config_init(dev); 1291 dev->config_pending = false; 1292 } 1293 1294 device_check_state(dev); 1295 1296 return dev; 1297 } 1298 1299 void 1300 device_dump_status(struct blob_buf *b, struct device *dev) 1301 { 1302 struct device_settings st; 1303 void *c, *s; 1304 1305 if (!dev) { 1306 avl_for_each_element(&devices, dev, avl) { 1307 if (!dev->present) 1308 continue; 1309 c = blobmsg_open_table(b, dev->ifname); 1310 device_dump_status(b, dev); 1311 blobmsg_close_table(b, c); 1312 } 1313 1314 return; 1315 } 1316 1317 blobmsg_add_u8(b, "external", dev->external); 1318 blobmsg_add_u8(b, "present", dev->present); 1319 blobmsg_add_string(b, "type", dev->type->name); 1320 1321 if (!dev->present) 1322 return; 1323 1324 blobmsg_add_u8(b, "up", !!dev->active); 1325 blobmsg_add_u8(b, "carrier", !!dev->link_active); 1326 blobmsg_add_u8(b, "auth_status", !!dev->auth_status); 1327 1328 if (dev->type->dump_info) 1329 dev->type->dump_info(dev, b); 1330 else 1331 system_if_dump_info(dev, b); 1332 1333 if (dev->active) { 1334 device_merge_settings(dev, &st); 1335 if (st.flags & DEV_OPT_MASTER) { 1336 char buf[64], *devname; 1337 1338 devname = if_indextoname(st.master_ifindex, buf); 1339 if (devname) 1340 blobmsg_add_string(b, "conduit", devname); 1341 } 1342 if (st.flags & DEV_OPT_MTU) 1343 blobmsg_add_u32(b, "mtu", st.mtu); 1344 if (st.flags & DEV_OPT_MTU6) 1345 blobmsg_add_u32(b, "mtu6", st.mtu6); 1346 if (st.flags & DEV_OPT_MACADDR) 1347 blobmsg_add_string(b, "macaddr", format_macaddr(st.macaddr)); 1348 if (st.flags & DEV_OPT_TXQUEUELEN) 1349 blobmsg_add_u32(b, "txqueuelen", st.txqueuelen); 1350 if (st.flags & DEV_OPT_IPV6) 1351 blobmsg_add_u8(b, "ipv6", st.ipv6); 1352 if (st.flags & DEV_OPT_IP6SEGMENTROUTING) 1353 blobmsg_add_u8(b, "ip6segmentrouting", st.ip6segmentrouting); 1354 if (st.flags & DEV_OPT_PROMISC) 1355 blobmsg_add_u8(b, "promisc", st.promisc); 1356 if (st.flags & DEV_OPT_RPFILTER) 1357 blobmsg_add_u32(b, "rpfilter", st.rpfilter); 1358 if (st.flags & DEV_OPT_ACCEPTLOCAL) 1359 blobmsg_add_u8(b, "acceptlocal", st.acceptlocal); 1360 if (st.flags & DEV_OPT_IGMPVERSION) 1361 blobmsg_add_u32(b, "igmpversion", st.igmpversion); 1362 if (st.flags & DEV_OPT_MLDVERSION) 1363 blobmsg_add_u32(b, "mldversion", st.mldversion); 1364 if (st.flags & DEV_OPT_NEIGHREACHABLETIME) { 1365 blobmsg_add_u32(b, "neigh4reachabletime", st.neigh4reachabletime); 1366 blobmsg_add_u32(b, "neigh6reachabletime", st.neigh6reachabletime); 1367 } 1368 if (st.flags & DEV_OPT_NEIGHGCSTALETIME) { 1369 blobmsg_add_u32(b, "neigh4gcstaletime", st.neigh4gcstaletime); 1370 blobmsg_add_u32(b, "neigh6gcstaletime", st.neigh6gcstaletime); 1371 } 1372 if (st.flags & DEV_OPT_NEIGHLOCKTIME) 1373 blobmsg_add_u32(b, "neigh4locktime", st.neigh4locktime); 1374 if (st.flags & DEV_OPT_DADTRANSMITS) 1375 blobmsg_add_u32(b, "dadtransmits", st.dadtransmits); 1376 if (st.flags & DEV_OPT_MULTICAST_TO_UNICAST) 1377 blobmsg_add_u8(b, "multicast_to_unicast", st.multicast_to_unicast); 1378 if (st.flags & DEV_OPT_MULTICAST_ROUTER) 1379 blobmsg_add_u32(b, "multicast_router", st.multicast_router); 1380 if (st.flags & DEV_OPT_MULTICAST_FAST_LEAVE) 1381 blobmsg_add_u8(b, "multicast_fast_leave", st.multicast_fast_leave); 1382 if (st.flags & DEV_OPT_MULTICAST) 1383 blobmsg_add_u8(b, "multicast", st.multicast); 1384 if (st.flags & DEV_OPT_LEARNING) 1385 blobmsg_add_u8(b, "learning", st.learning); 1386 if (st.flags & DEV_OPT_UNICAST_FLOOD) 1387 blobmsg_add_u8(b, "unicast_flood", st.unicast_flood); 1388 if (st.flags & DEV_OPT_SENDREDIRECTS) 1389 blobmsg_add_u8(b, "sendredirects", st.sendredirects); 1390 if (st.flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST) 1391 blobmsg_add_u8(b, "drop_v4_unicast_in_l2_multicast", st.drop_v4_unicast_in_l2_multicast); 1392 if (st.flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST) 1393 blobmsg_add_u8(b, "drop_v6_unicast_in_l2_multicast", st.drop_v6_unicast_in_l2_multicast); 1394 if (st.flags & DEV_OPT_DROP_GRATUITOUS_ARP) 1395 blobmsg_add_u8(b, "drop_gratuitous_arp", st.drop_gratuitous_arp); 1396 if (st.flags & DEV_OPT_DROP_UNSOLICITED_NA) 1397 blobmsg_add_u8(b, "drop_unsolicited_na", st.drop_unsolicited_na); 1398 if (st.flags & DEV_OPT_ARP_ACCEPT) 1399 blobmsg_add_u8(b, "arp_accept", st.arp_accept); 1400 if (st.flags & DEV_OPT_AUTH) 1401 blobmsg_add_u8(b, "auth", st.auth); 1402 if (st.flags & DEV_OPT_GRO) 1403 blobmsg_add_u8(b, "gro", st.gro); 1404 if (st.flags & DEV_OPT_EEE) 1405 blobmsg_add_u8(b, "eee", st.eee); 1406 } 1407 1408 s = blobmsg_open_table(b, "statistics"); 1409 if (dev->type->dump_stats) 1410 dev->type->dump_stats(dev, b); 1411 else 1412 system_if_dump_stats(dev, b); 1413 blobmsg_close_table(b, s); 1414 } 1415 1416 static void __init simple_device_type_init(void) 1417 { 1418 device_type_add(&simple_device_type); 1419 } 1420 1421 void device_hotplug_event(const char *name, bool add) 1422 { 1423 struct device *dev; 1424 1425 wireless_device_hotplug_event(name, add); 1426 1427 dev = device_find(name); 1428 if (!dev || dev->type != &simple_device_type) 1429 return; 1430 1431 device_set_present(dev, add); 1432 } 1433
This page was automatically generated by LXR 0.3.1. • OpenWrt