• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/netifd/device.c

  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 "ucode.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_BROADCAST_FLOOD] = { .name ="broadcast_flood", .type = BLOBMSG_TYPE_BOOL },
 58         [DEV_ATTR_SENDREDIRECTS] = { .name = "sendredirects", .type = BLOBMSG_TYPE_BOOL },
 59         [DEV_ATTR_NEIGHLOCKTIME] = { .name = "neighlocktime", .type = BLOBMSG_TYPE_INT32 },
 60         [DEV_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL },
 61         [DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST] = { .name = "drop_v4_unicast_in_l2_multicast", .type = BLOBMSG_TYPE_BOOL },
 62         [DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST] = { .name = "drop_v6_unicast_in_l2_multicast", .type = BLOBMSG_TYPE_BOOL },
 63         [DEV_ATTR_DROP_GRATUITOUS_ARP] = { .name = "drop_gratuitous_arp", .type = BLOBMSG_TYPE_BOOL },
 64         [DEV_ATTR_DROP_UNSOLICITED_NA] = { .name = "drop_unsolicited_na", .type = BLOBMSG_TYPE_BOOL },
 65         [DEV_ATTR_ARP_ACCEPT] = { .name = "arp_accept", .type = BLOBMSG_TYPE_BOOL },
 66         [DEV_ATTR_AUTH] = { .name = "auth", .type = BLOBMSG_TYPE_BOOL },
 67         [DEV_ATTR_AUTH_VLAN] = { .name = "auth_vlan", BLOBMSG_TYPE_ARRAY },
 68         [DEV_ATTR_SPEED] = { .name = "speed", .type = BLOBMSG_TYPE_INT32 },
 69         [DEV_ATTR_DUPLEX] = { .name = "duplex", .type = BLOBMSG_TYPE_BOOL },
 70         [DEV_ATTR_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_ARRAY },
 71         [DEV_ATTR_PAUSE] = { .name = "pause", .type = BLOBMSG_TYPE_BOOL },
 72         [DEV_ATTR_ASYM_PAUSE] = { .name = "asym_pause", .type = BLOBMSG_TYPE_BOOL },
 73         [DEV_ATTR_RXPAUSE] = { .name = "rxpause", .type = BLOBMSG_TYPE_BOOL },
 74         [DEV_ATTR_TXPAUSE] = { .name = "txpause", .type = BLOBMSG_TYPE_BOOL },
 75         [DEV_ATTR_AUTONEG] = { .name = "autoneg", .type = BLOBMSG_TYPE_BOOL },
 76         [DEV_ATTR_GRO] = { .name = "gro", .type = BLOBMSG_TYPE_BOOL },
 77         [DEV_ATTR_MASTER] = { .name = "conduit", .type = BLOBMSG_TYPE_STRING },
 78         [DEV_ATTR_EEE] = { .name = "eee", .type = BLOBMSG_TYPE_BOOL },
 79         [DEV_ATTR_TAGS] = { .name = "tags", .type = BLOBMSG_TYPE_ARRAY },
 80         [DEV_ATTR_PSE] = { .name = "pse", .type = BLOBMSG_TYPE_BOOL },
 81         [DEV_ATTR_PSE_PODL] = { .name = "pse_podl", .type = BLOBMSG_TYPE_BOOL },
 82         [DEV_ATTR_PSE_POWER_LIMIT] = { .name = "pse_power_limit", .type = BLOBMSG_TYPE_INT32 },
 83         [DEV_ATTR_PSE_PRIORITY] = { .name = "pse_priority", .type = BLOBMSG_TYPE_INT32 },
 84 };
 85 
 86 const struct uci_blob_param_list device_attr_list = {
 87         .n_params = __DEV_ATTR_MAX,
 88         .params = dev_attrs,
 89 };
 90 
 91 int device_type_add(struct device_type *devtype)
 92 {
 93         if (device_type_get(devtype->name)) {
 94                 netifd_log_message(L_WARNING, "Device handler '%s' already exists\n",
 95                                    devtype->name);
 96                 return 1;
 97         }
 98 
 99         netifd_log_message(L_NOTICE, "Added device handler type: %s\n",
100                 devtype->name);
101 
102         list_add(&devtype->list, &devtypes);
103         return 0;
104 }
105 
106 struct device_type *
107 device_type_get(const char *tname)
108 {
109         struct device_type *cur;
110 
111         list_for_each_entry(cur, &devtypes, list)
112                 if (!strcmp(cur->name, tname))
113                         return cur;
114 
115         return NULL;
116 }
117 
118 static int device_vlan_len(struct kvlist *kv, const void *data)
119 {
120         return sizeof(unsigned int);
121 }
122 
123 void device_vlan_update(bool done)
124 {
125         struct device *dev;
126 
127         avl_for_each_element(&devices, dev, avl) {
128                 if (!dev->vlans.update)
129                         continue;
130 
131                 if (!done) {
132                         if (dev->vlan_aliases.get_len)
133                                 kvlist_free(&dev->vlan_aliases);
134                         else
135                                 kvlist_init(&dev->vlan_aliases, device_vlan_len);
136                         vlist_update(&dev->vlans);
137                 } else {
138                         vlist_flush(&dev->vlans);
139 
140                         if (dev->type->vlan_update)
141                                 dev->type->vlan_update(dev);
142 
143                         device_broadcast_event(dev, DEV_EVENT_VLAN_UPDATE);
144                 }
145         }
146 }
147 
148 void device_type_for_each(const struct device_type *type,
149                           void (*cb)(struct device *dev))
150 {
151         struct device *dev, *tmp;
152 
153         avl_for_each_element_safe(&devices, dev, avl, tmp) {
154                 if (dev->type == type)
155                         cb(dev);
156         }
157 }
158 
159 void device_stp_init(void)
160 {
161         struct device *dev;
162 
163         avl_for_each_element(&devices, dev, avl) {
164                 if (!dev->type->stp_init)
165                         continue;
166 
167                 dev->type->stp_init(dev);
168         }
169 }
170 
171 static int set_device_state(struct device *dev, bool state)
172 {
173         if (state) {
174                 /* Get ifindex for all devices being enabled so a valid  */
175                 /* ifindex is in place avoiding possible race conditions */
176                 device_set_ifindex(dev, system_if_resolve(dev));
177                 if (!dev->ifindex)
178                         return -1;
179 
180                 system_if_get_settings(dev, &dev->orig_settings);
181                 /* Only keep orig settings based on what needs to be set */
182                 dev->orig_settings.valid_flags = dev->orig_settings.flags;
183                 dev->orig_settings.flags &= dev->settings.flags;
184                 system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
185 
186                 if (!dev->external)
187                         system_if_up(dev);
188 
189                 system_if_apply_settings_after_up(dev, &dev->settings);
190         } else {
191                 if (!dev->external)
192                         system_if_down(dev);
193                 system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
194 
195                 /* Restore any settings present in UCI which may have
196                  * failed to apply so that they will be re-attempted
197                  * the next time the device is brought up */
198                 dev->settings.flags |= dev->settings.valid_flags;
199         }
200 
201         return 0;
202 }
203 
204 static int
205 simple_device_set_state(struct device *dev, bool state)
206 {
207         struct device *pdev;
208         int ret = 0;
209 
210         pdev = dev->parent.dev;
211         if (state && !pdev) {
212                 pdev = system_if_get_parent(dev);
213                 if (pdev)
214                         device_add_user(&dev->parent, pdev);
215         }
216 
217         if (pdev) {
218                 if (state)
219                         ret = device_claim(&dev->parent);
220                 else
221                         device_release(&dev->parent);
222 
223                 if (ret < 0)
224                         return ret;
225         }
226 
227         ret = set_device_state(dev, state);
228         if (ret && state && pdev)
229                 device_release(&dev->parent);
230 
231         return ret;
232 }
233 
234 static struct device *
235 simple_device_create(const char *name, struct device_type *devtype,
236                      struct blob_attr *attr)
237 {
238         struct blob_attr *tb[__DEV_ATTR_MAX];
239         struct device *dev = NULL;
240 
241         /* device type is unused for simple devices */
242         devtype = NULL;
243 
244         blobmsg_parse_attr(dev_attrs, __DEV_ATTR_MAX, tb, attr);
245         dev = device_get(name, true);
246         if (!dev)
247                 return NULL;
248 
249         dev->set_state = simple_device_set_state;
250         device_init_settings(dev, tb);
251 
252         return dev;
253 }
254 
255 static void simple_device_free(struct device *dev)
256 {
257         if (dev->parent.dev)
258                 device_remove_user(&dev->parent);
259         free(dev);
260 }
261 
262 struct device_type simple_device_type = {
263         .name = "Network device",
264         .config_params = &device_attr_list,
265 
266         .create = simple_device_create,
267         .check_state = system_if_check,
268         .free = simple_device_free,
269 };
270 
271 void
272 device_merge_settings(struct device *dev, struct device_settings *n)
273 {
274         struct device_settings *os = &dev->orig_settings;
275         struct device_settings *s = &dev->settings;
276 
277         BUILD_BUG_ON(__DEV_ATTR_MAX > 64);
278 
279         memset(n, 0, sizeof(*n));
280         n->mtu = s->flags & DEV_OPT_MTU ? s->mtu : os->mtu;
281         n->mtu6 = s->flags & DEV_OPT_MTU6 ? s->mtu6 : os->mtu6;
282         n->txqueuelen = s->flags & DEV_OPT_TXQUEUELEN ?
283                 s->txqueuelen : os->txqueuelen;
284         memcpy(n->macaddr,
285                 (s->flags & (DEV_OPT_MACADDR|DEV_OPT_DEFAULT_MACADDR) ? s->macaddr : os->macaddr),
286                 sizeof(n->macaddr));
287         n->ipv6 = s->flags & DEV_OPT_IPV6 ? s->ipv6 : os->ipv6;
288         n->ip6segmentrouting = s->flags & DEV_OPT_IP6SEGMENTROUTING ? s->ip6segmentrouting : os->ip6segmentrouting;
289         n->promisc = s->flags & DEV_OPT_PROMISC ? s->promisc : os->promisc;
290         n->rpfilter = s->flags & DEV_OPT_RPFILTER ? s->rpfilter : os->rpfilter;
291         n->acceptlocal = s->flags & DEV_OPT_ACCEPTLOCAL ? s->acceptlocal : os->acceptlocal;
292         n->igmpversion = s->flags & DEV_OPT_IGMPVERSION ? s->igmpversion : os->igmpversion;
293         n->mldversion = s->flags & DEV_OPT_MLDVERSION ? s->mldversion : os->mldversion;
294         n->neigh4reachabletime = s->flags & DEV_OPT_NEIGHREACHABLETIME ?
295                 s->neigh4reachabletime : os->neigh4reachabletime;
296         n->neigh6reachabletime = s->flags & DEV_OPT_NEIGHREACHABLETIME ?
297                 s->neigh6reachabletime : os->neigh6reachabletime;
298         n->neigh4gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ?
299                 s->neigh4gcstaletime : os->neigh4gcstaletime;
300         n->neigh6gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ?
301                 s->neigh6gcstaletime : os->neigh6gcstaletime;
302         n->neigh4locktime = s->flags & DEV_OPT_NEIGHLOCKTIME ?
303                 s->neigh4locktime : os->neigh4locktime;
304         n->dadtransmits = s->flags & DEV_OPT_DADTRANSMITS ?
305                 s->dadtransmits : os->dadtransmits;
306         n->multicast = s->flags & DEV_OPT_MULTICAST ?
307                 s->multicast : os->multicast;
308         n->multicast_to_unicast = s->multicast_to_unicast;
309         n->multicast_router = s->multicast_router;
310         n->multicast_fast_leave = s->multicast_fast_leave;
311         n->learning = s->learning;
312         n->unicast_flood = s->unicast_flood;
313         n->broadcast_flood = s->broadcast_flood;
314         n->sendredirects = s->flags & DEV_OPT_SENDREDIRECTS ?
315                 s->sendredirects : os->sendredirects;
316         n->drop_v4_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST ?
317                 s->drop_v4_unicast_in_l2_multicast : os->drop_v4_unicast_in_l2_multicast;
318         n->drop_v6_unicast_in_l2_multicast = s->flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST ?
319                 s->drop_v6_unicast_in_l2_multicast : os->drop_v6_unicast_in_l2_multicast;
320         n->drop_gratuitous_arp = s->flags & DEV_OPT_DROP_GRATUITOUS_ARP ?
321                 s->drop_gratuitous_arp : os->drop_gratuitous_arp;
322         n->drop_unsolicited_na = s->flags & DEV_OPT_DROP_UNSOLICITED_NA ?
323                 s->drop_unsolicited_na : os->drop_unsolicited_na;
324         n->arp_accept = s->flags & DEV_OPT_ARP_ACCEPT ?
325                 s->arp_accept : os->arp_accept;
326         n->auth = s->flags & DEV_OPT_AUTH ? s->auth : os->auth;
327         n->speed = s->flags & DEV_OPT_SPEED ? s->speed : os->speed;
328         n->duplex = s->flags & DEV_OPT_DUPLEX ? s->duplex : os->duplex;
329         n->pause = s->flags & DEV_OPT_PAUSE ? s->pause : os->pause;
330         n->asym_pause = s->flags & DEV_OPT_ASYM_PAUSE ? s->asym_pause : os->asym_pause;
331         n->rxpause = s->flags & DEV_OPT_RXPAUSE ? s->rxpause : os->rxpause;
332         n->txpause = s->flags & DEV_OPT_TXPAUSE ? s->txpause : os->txpause;
333         n->autoneg = s->flags & DEV_OPT_AUTONEG ? s->autoneg : os->autoneg;
334         n->gro = s->flags & DEV_OPT_GRO ? s->gro : os->gro;
335         n->eee = s->flags & DEV_OPT_EEE ? s->eee : os->eee;
336         n->master_ifindex = s->flags & DEV_OPT_MASTER ? s->master_ifindex : os->master_ifindex;
337         n->pse = s->flags & DEV_OPT_PSE ? s->pse : os->pse;
338         n->pse_podl = s->flags & DEV_OPT_PSE_PODL ? s->pse_podl : os->pse_podl;
339         n->pse_power_limit = s->flags & DEV_OPT_PSE_POWER_LIMIT ? s->pse_power_limit : os->pse_power_limit;
340         n->pse_priority = s->flags & DEV_OPT_PSE_PRIORITY ? s->pse_priority : os->pse_priority;
341         n->flags = s->flags | os->flags | os->valid_flags;
342 }
343 
344 static bool device_fill_vlan_range(struct device_vlan_range *r, const char *val)
345 {
346         unsigned long cur_start, cur_end;
347         char *sep;
348 
349         cur_start = strtoul(val, &sep, 0);
350         cur_end = cur_start;
351 
352         if (*sep == '-')
353                 cur_end = strtoul(sep + 1, &sep, 0);
354         if (*sep || cur_end < cur_start ||
355             !cur_start || cur_end > 4095)
356                 return false;
357 
358         r->start = cur_start;
359         r->end = cur_end;
360 
361         return true;
362 }
363 
364 static void
365 device_set_extra_vlans(struct device *dev, struct blob_attr *data)
366 {
367         struct blob_attr *cur;
368         int n_vlans;
369         size_t rem;
370 
371         dev->n_extra_vlan = 0;
372         if (!data)
373                 return;
374 
375         n_vlans = blobmsg_check_array(data, BLOBMSG_TYPE_STRING);
376         if (n_vlans < 1)
377                 return;
378 
379         dev->extra_vlan = realloc(dev->extra_vlan, n_vlans * sizeof(*dev->extra_vlan));
380         blobmsg_for_each_attr(cur, data, rem)
381                 if (device_fill_vlan_range(&dev->extra_vlan[dev->n_extra_vlan],
382                                            blobmsg_get_string(cur)))
383                         dev->n_extra_vlan++;
384 }
385 
386 void
387 device_init_settings(struct device *dev, struct blob_attr **tb)
388 {
389         struct device_settings *s = &dev->settings;
390         struct blob_attr *cur;
391         struct ether_addr *ea;
392         bool disabled = false;
393 
394         if (dev->wireless)
395                 s->flags &= DEV_OPT_ISOLATE;
396         else
397                 s->flags = 0;
398         if ((cur = tb[DEV_ATTR_ENABLED]))
399                 disabled = !blobmsg_get_bool(cur);
400 
401         if ((cur = tb[DEV_ATTR_MTU]) && blobmsg_get_u32(cur) >= 68) {
402                 s->mtu = blobmsg_get_u32(cur);
403                 s->flags |= DEV_OPT_MTU;
404         }
405 
406         if ((cur = tb[DEV_ATTR_MTU6]) && blobmsg_get_u32(cur) >= 1280) {
407                 s->mtu6 = blobmsg_get_u32(cur);
408                 s->flags |= DEV_OPT_MTU6;
409         }
410 
411         if ((cur = tb[DEV_ATTR_TXQUEUELEN])) {
412                 s->txqueuelen = blobmsg_get_u32(cur);
413                 s->flags |= DEV_OPT_TXQUEUELEN;
414         }
415 
416         if ((cur = tb[DEV_ATTR_MACADDR])) {
417                 ea = ether_aton(blobmsg_data(cur));
418                 if (ea) {
419                         memcpy(s->macaddr, ea, 6);
420                         s->flags |= DEV_OPT_MACADDR;
421                 }
422         }
423 
424         if ((cur = tb[DEV_ATTR_IPV6])) {
425                 s->ipv6 = blobmsg_get_bool(cur);
426                 s->flags |= DEV_OPT_IPV6;
427         }
428 
429         if ((cur = tb[DEV_ATTR_IP6SEGMENTROUTING])) {
430                 s->ip6segmentrouting = blobmsg_get_bool(cur);
431                 s->flags |= DEV_OPT_IP6SEGMENTROUTING;
432         }
433 
434         if ((cur = tb[DEV_ATTR_PROMISC])) {
435                 s->promisc = blobmsg_get_bool(cur);
436                 s->flags |= DEV_OPT_PROMISC;
437         }
438 
439         if ((cur = tb[DEV_ATTR_RPFILTER])) {
440                 if (system_resolve_rpfilter(blobmsg_data(cur), &s->rpfilter))
441                         s->flags |= DEV_OPT_RPFILTER;
442                 else
443                         D(DEVICE, "Failed to resolve rpfilter: %s", (char *) blobmsg_data(cur));
444         }
445 
446         if ((cur = tb[DEV_ATTR_ACCEPTLOCAL])) {
447                 s->acceptlocal = blobmsg_get_bool(cur);
448                 s->flags |= DEV_OPT_ACCEPTLOCAL;
449         }
450 
451         if ((cur = tb[DEV_ATTR_IGMPVERSION])) {
452                 s->igmpversion = blobmsg_get_u32(cur);
453                 if (s->igmpversion >= 1 && s->igmpversion <= 3)
454                         s->flags |= DEV_OPT_IGMPVERSION;
455                 else
456                         D(DEVICE, "Failed to resolve igmpversion: %d", blobmsg_get_u32(cur));
457         }
458 
459         if ((cur = tb[DEV_ATTR_MLDVERSION])) {
460                 s->mldversion = blobmsg_get_u32(cur);
461                 if (s->mldversion >= 1 && s->mldversion <= 2)
462                         s->flags |= DEV_OPT_MLDVERSION;
463                 else
464                         D(DEVICE, "Failed to resolve mldversion: %d", blobmsg_get_u32(cur));
465         }
466 
467         if ((cur = tb[DEV_ATTR_NEIGHREACHABLETIME])) {
468                 s->neigh6reachabletime = s->neigh4reachabletime = blobmsg_get_u32(cur);
469                 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
470         }
471 
472         if ((cur = tb[DEV_ATTR_NEIGHGCSTALETIME])) {
473                 s->neigh6gcstaletime = s->neigh4gcstaletime = blobmsg_get_u32(cur);
474                 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
475         }
476 
477         if ((cur = tb[DEV_ATTR_NEIGHLOCKTIME])) {
478                 s->neigh4locktime = blobmsg_get_u32(cur);
479                 s->flags |= DEV_OPT_NEIGHLOCKTIME;
480         }
481 
482         if ((cur = tb[DEV_ATTR_DADTRANSMITS])) {
483                 s->dadtransmits = blobmsg_get_u32(cur);
484                 s->flags |= DEV_OPT_DADTRANSMITS;
485         }
486 
487         if ((cur = tb[DEV_ATTR_MULTICAST_TO_UNICAST])) {
488                 s->multicast_to_unicast = blobmsg_get_bool(cur);
489                 s->flags |= DEV_OPT_MULTICAST_TO_UNICAST;
490         }
491 
492         if ((cur = tb[DEV_ATTR_MULTICAST_ROUTER])) {
493                 s->multicast_router = blobmsg_get_u32(cur);
494                 if (s->multicast_router <= 2)
495                         s->flags |= DEV_OPT_MULTICAST_ROUTER;
496                 else
497                         D(DEVICE, "Invalid value: %d - (Use 0: never, 1: learn, 2: always)", blobmsg_get_u32(cur));
498         }
499 
500         if ((cur = tb[DEV_ATTR_MULTICAST_FAST_LEAVE])) {
501                 s->multicast_fast_leave = blobmsg_get_bool(cur);
502                 s->flags |= DEV_OPT_MULTICAST_FAST_LEAVE;
503         }
504 
505         if ((cur = tb[DEV_ATTR_MULTICAST])) {
506                 s->multicast = blobmsg_get_bool(cur);
507                 s->flags |= DEV_OPT_MULTICAST;
508         }
509 
510         if ((cur = tb[DEV_ATTR_LEARNING])) {
511                 s->learning = blobmsg_get_bool(cur);
512                 s->flags |= DEV_OPT_LEARNING;
513         }
514 
515         if ((cur = tb[DEV_ATTR_UNICAST_FLOOD])) {
516                 s->unicast_flood = blobmsg_get_bool(cur);
517                 s->flags |= DEV_OPT_UNICAST_FLOOD;
518         }
519 
520         if ((cur = tb[DEV_ATTR_BROADCAST_FLOOD])) {
521                 s->broadcast_flood = blobmsg_get_bool(cur);
522                 s->flags |= DEV_OPT_BROADCAST_FLOOD;
523         }
524 
525         if ((cur = tb[DEV_ATTR_SENDREDIRECTS])) {
526                 s->sendredirects = blobmsg_get_bool(cur);
527                 s->flags |= DEV_OPT_SENDREDIRECTS;
528         }
529 
530         if ((cur = tb[DEV_ATTR_ISOLATE])) {
531                 s->isolate = blobmsg_get_bool(cur);
532                 s->flags |= DEV_OPT_ISOLATE;
533         }
534 
535         if ((cur = tb[DEV_ATTR_DROP_V4_UNICAST_IN_L2_MULTICAST])) {
536                 s->drop_v4_unicast_in_l2_multicast = blobmsg_get_bool(cur);
537                 s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST;
538         }
539 
540         if ((cur = tb[DEV_ATTR_DROP_V6_UNICAST_IN_L2_MULTICAST])) {
541                 s->drop_v6_unicast_in_l2_multicast = blobmsg_get_bool(cur);
542                 s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST;
543         }
544 
545         if ((cur = tb[DEV_ATTR_DROP_GRATUITOUS_ARP])) {
546                 s->drop_gratuitous_arp = blobmsg_get_bool(cur);
547                 s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP;
548         }
549 
550         if ((cur = tb[DEV_ATTR_DROP_UNSOLICITED_NA])) {
551                 s->drop_unsolicited_na = blobmsg_get_bool(cur);
552                 s->flags |= DEV_OPT_DROP_UNSOLICITED_NA;
553         }
554 
555         if ((cur = tb[DEV_ATTR_ARP_ACCEPT])) {
556                 s->arp_accept = blobmsg_get_bool(cur);
557                 s->flags |= DEV_OPT_ARP_ACCEPT;
558         }
559 
560         if ((cur = tb[DEV_ATTR_AUTH])) {
561                 s->auth = blobmsg_get_bool(cur);
562                 s->flags |= DEV_OPT_AUTH;
563         }
564 
565         if ((cur = tb[DEV_ATTR_SPEED])) {
566                 s->speed = blobmsg_get_u32(cur);
567                 s->flags |= DEV_OPT_SPEED;
568         }
569 
570         if ((cur = tb[DEV_ATTR_DUPLEX])) {
571                 s->duplex = blobmsg_get_bool(cur);
572                 s->flags |= DEV_OPT_DUPLEX;
573         }
574 
575         if ((cur = tb[DEV_ATTR_PAUSE])) {
576                 s->pause = blobmsg_get_bool(cur);
577                 s->flags |= DEV_OPT_PAUSE;
578         }
579 
580         if ((cur = tb[DEV_ATTR_ASYM_PAUSE])) {
581                 s->asym_pause = blobmsg_get_bool(cur);
582                 s->flags |= DEV_OPT_ASYM_PAUSE;
583         }
584 
585         if ((cur = tb[DEV_ATTR_RXPAUSE])) {
586                 s->rxpause = blobmsg_get_bool(cur);
587                 s->flags |= DEV_OPT_RXPAUSE;
588         }
589 
590         if ((cur = tb[DEV_ATTR_TXPAUSE])) {
591                 s->txpause = blobmsg_get_bool(cur);
592                 s->flags |= DEV_OPT_TXPAUSE;
593         }
594 
595         if ((cur = tb[DEV_ATTR_AUTONEG])) {
596                 s->autoneg = blobmsg_get_bool(cur);
597                 s->flags |= DEV_OPT_AUTONEG;
598         }
599 
600         if ((cur = tb[DEV_ATTR_GRO])) {
601                 s->gro = blobmsg_get_bool(cur);
602                 s->flags |= DEV_OPT_GRO;
603         }
604 
605         if ((cur = tb[DEV_ATTR_MASTER])) {
606                 char *ifname = blobmsg_get_string(cur);
607                 s->master_ifindex = if_nametoindex(ifname);
608                 s->flags |= DEV_OPT_MASTER;
609         }
610 
611         if ((cur = tb[DEV_ATTR_EEE])) {
612                 s->eee = blobmsg_get_bool(cur);
613                 s->flags |= DEV_OPT_EEE;
614         }
615 
616         if ((cur = tb[DEV_ATTR_PSE])) {
617                 s->pse = blobmsg_get_bool(cur);
618                 s->flags |= DEV_OPT_PSE;
619         }
620 
621         if ((cur = tb[DEV_ATTR_PSE_PODL])) {
622                 s->pse_podl = blobmsg_get_bool(cur);
623                 s->flags |= DEV_OPT_PSE_PODL;
624         }
625 
626         if ((cur = tb[DEV_ATTR_PSE_POWER_LIMIT])) {
627                 s->pse_power_limit = blobmsg_get_u32(cur);
628                 s->flags |= DEV_OPT_PSE_POWER_LIMIT;
629         }
630 
631         if ((cur = tb[DEV_ATTR_PSE_PRIORITY])) {
632                 s->pse_priority = blobmsg_get_u32(cur);
633                 s->flags |= DEV_OPT_PSE_PRIORITY;
634         }
635 
636         /* Remember the settings present in UCI */
637         s->valid_flags = s->flags;
638 
639         cur = tb[DEV_ATTR_AUTH_VLAN];
640         free(dev->config_auth_vlans);
641         dev->config_auth_vlans = cur ? blob_memdup(cur) : NULL;
642 
643         cur = tb[DEV_ATTR_TAGS];
644         free(dev->tags);
645         dev->tags = cur ? blob_memdup(cur) : NULL;
646 
647         device_set_extra_vlans(dev, tb[DEV_ATTR_VLAN]);
648         device_set_disabled(dev, disabled);
649 }
650 
651 static void __init dev_init(void)
652 {
653         avl_init(&devices, avl_strcmp, true, NULL);
654 }
655 
656 static int device_release_cb(void *ctx, struct safe_list *list)
657 {
658         struct device_user *dep = container_of(list, struct device_user, list);
659 
660         if (!dep->dev || !dep->claimed)
661                 return 0;
662 
663         device_release(dep);
664         return 0;
665 }
666 
667 static int device_broadcast_cb(void *ctx, struct safe_list *list)
668 {
669         struct device_user *dep = container_of(list, struct device_user, list);
670         int *ev = ctx;
671 
672         /* device might have been removed by an earlier callback */
673         if (!dep->dev)
674                 return 0;
675 
676         if (dep->cb)
677                 dep->cb(dep, *ev);
678         return 0;
679 }
680 
681 const char *device_event_name(enum device_event ev)
682 {
683         static const char * const event_names[] = {
684                 [DEV_EVENT_ADD] = "add",
685                 [DEV_EVENT_REMOVE] = "remove",
686                 [DEV_EVENT_UPDATE_IFNAME] = "update_ifname",
687                 [DEV_EVENT_UPDATE_IFINDEX] = "update_ifindex",
688                 [DEV_EVENT_SETUP] = "setup",
689                 [DEV_EVENT_TEARDOWN] = "teardown",
690                 [DEV_EVENT_UP] = "up",
691                 [DEV_EVENT_DOWN] = "down",
692                 [DEV_EVENT_AUTH_UP] = "auth_up",
693                 [DEV_EVENT_LINK_UP] = "link_up",
694                 [DEV_EVENT_LINK_DOWN] = "link_down",
695                 [DEV_EVENT_TOPO_CHANGE] = "topo_change",
696                 [DEV_EVENT_VLAN_UPDATE] = "vlan_update",
697         };
698 
699         if (ev >= ARRAY_SIZE(event_names) || !event_names[ev])
700                 return "unknown";
701 
702         return event_names[ev];
703 }
704 
705 void __device_broadcast_event(struct device *dev, enum device_event ev)
706 {
707         const char *ev_name;
708         int dev_ev = ev;
709 
710         safe_list_for_each(&dev->aliases, device_broadcast_cb, &dev_ev);
711         safe_list_for_each(&dev->users, device_broadcast_cb, &dev_ev);
712 
713         switch (ev) {
714         case DEV_EVENT_ADD:
715         case DEV_EVENT_REMOVE:
716         case DEV_EVENT_UP:
717         case DEV_EVENT_DOWN:
718         case DEV_EVENT_AUTH_UP:
719         case DEV_EVENT_LINK_UP:
720         case DEV_EVENT_LINK_DOWN:
721         case DEV_EVENT_TOPO_CHANGE:
722                 break;
723         default:
724                 return;
725         }
726 
727         ev_name = device_event_name(ev);
728         if (!dev->ifname[0])
729                 return;
730 
731         blob_buf_init(&b, 0);
732         blobmsg_add_string(&b, "name", dev->ifname);
733         blobmsg_add_u8(&b, "auth_status", dev->auth_status);
734         blobmsg_add_u8(&b, "present", dev->present);
735         blobmsg_add_u8(&b, "active", dev->active);
736         blobmsg_add_u8(&b, "link_active", dev->link_active);
737         netifd_ubus_device_notify(ev_name, b.head, -1);
738 }
739 
740 static void
741 device_fill_default_settings(struct device *dev)
742 {
743         struct device_settings *s = &dev->settings;
744         struct ether_addr *ea;
745         const char *master;
746         int ret;
747 
748         if (!(s->flags & DEV_OPT_MACADDR)) {
749                 ea = config_get_default_macaddr(dev->ifname);
750                 if (ea) {
751                         memcpy(s->macaddr, ea, 6);
752                         s->flags |= DEV_OPT_DEFAULT_MACADDR;
753                 }
754         }
755 
756         if (!(s->flags & DEV_OPT_GRO)) {
757                 ret = config_get_default_gro(dev->ifname);
758                 if (ret >= 0) {
759                         s->gro = ret;
760                         s->flags |= DEV_OPT_GRO;
761                 }
762         }
763 
764         if (!(s->flags & DEV_OPT_MASTER)) {
765                 master = config_get_default_conduit(dev->ifname);
766                 if (master) {
767                         s->master_ifindex = if_nametoindex(master);
768                         s->flags |= DEV_OPT_MASTER;
769                 }
770         }
771 }
772 
773 int device_claim(struct device_user *dep)
774 {
775         struct device *dev = dep->dev;
776         int ret = 0;
777 
778         if (dep->claimed)
779                 return 0;
780 
781         if (!dev)
782                 return -1;
783 
784         dep->claimed = true;
785         D(DEVICE, "Claim %s %s, new active count: %d", dev->type->name, dev->ifname, dev->active + 1);
786         if (++dev->active != 1)
787                 return 0;
788 
789         device_broadcast_event(dev, DEV_EVENT_SETUP);
790         device_fill_default_settings(dev);
791         ret = dev->set_state(dev, true);
792         if (ret == 0)
793                 device_broadcast_event(dev, DEV_EVENT_UP);
794         else {
795                 D(DEVICE, "claim %s %s failed: %d", dev->type->name, dev->ifname, ret);
796                 dev->active = 0;
797                 dep->claimed = false;
798         }
799 
800         return ret;
801 }
802 
803 void device_release(struct device_user *dep)
804 {
805         struct device *dev = dep->dev;
806 
807         if (!dep->claimed)
808                 return;
809 
810         dep->claimed = false;
811         dev->active--;
812         D(DEVICE, "Release %s %s, new active count: %d", dev->type->name, dev->ifname, dev->active);
813         assert(dev->active >= 0);
814 
815         if (dev->active)
816                 return;
817 
818         device_broadcast_event(dev, DEV_EVENT_TEARDOWN);
819         dev->set_state(dev, false);
820 
821         if (dev->active)
822                 return;
823 
824         device_broadcast_event(dev, DEV_EVENT_DOWN);
825 }
826 
827 int device_check_state(struct device *dev)
828 {
829         if (!dev->type->check_state)
830                 return simple_device_type.check_state(dev);
831 
832         return dev->type->check_state(dev);
833 }
834 
835 int device_init_virtual(struct device *dev, struct device_type *type, const char *name)
836 {
837         assert(dev);
838         assert(type);
839 
840         D(DEVICE, "Initialize device '%s'", name ? name : "");
841         INIT_SAFE_LIST(&dev->users);
842         INIT_SAFE_LIST(&dev->aliases);
843         dev->type = type;
844 
845         if (name) {
846                 int ret;
847 
848                 ret = device_set_ifname(dev, name);
849                 if (ret < 0) {
850                         netifd_log_message(L_WARNING, "Failed to initalize device '%s'\n", name);
851                         return ret;
852                 }
853         }
854 
855         if (!dev->set_state)
856                 dev->set_state = set_device_state;
857 
858         return 0;
859 }
860 
861 int device_init(struct device *dev, struct device_type *type, const char *ifname)
862 {
863         int ret;
864 
865         ret = device_init_virtual(dev, type, ifname);
866         if (ret < 0)
867                 return ret;
868 
869         dev->avl.key = dev->ifname;
870 
871         ret = avl_insert(&devices, &dev->avl);
872         if (ret < 0)
873                 return ret;
874 
875         system_if_clear_state(dev);
876 
877         return 0;
878 }
879 
880 static struct device *
881 device_create_default(const char *name, bool external)
882 {
883         struct device *dev;
884 
885         if (!external && system_if_force_external(name))
886                 return NULL;
887 
888         D(DEVICE, "Create simple device '%s'", name);
889         dev = calloc(1, sizeof(*dev));
890         if (!dev)
891                 return NULL;
892 
893         dev->external = external;
894         dev->set_state = simple_device_set_state;
895 
896         if (device_init(dev, &simple_device_type, name) < 0) {
897                 device_cleanup(dev);
898                 free(dev);
899                 return NULL;
900         }
901 
902         dev->default_config = true;
903         device_check_state(dev);
904 
905         return dev;
906 }
907 
908 struct device *
909 device_find(const char *name)
910 {
911         struct device *dev;
912 
913         return avl_find_element(&devices, name, dev, avl);
914 }
915 
916 struct device *
917 __device_get(const char *name, int create, bool check_vlan)
918 {
919         struct device *dev;
920 
921         dev = avl_find_element(&devices, name, dev, avl);
922 
923         if (!dev && check_vlan && strchr(name, '.'))
924                 return get_vlan_device_chain(name, create);
925 
926         if (name[0] == '@')
927                 return device_alias_get(name + 1);
928 
929         if (dev) {
930                 if (create > 1 && !dev->external) {
931                         dev->external = true;
932                         device_set_present(dev, true);
933                 }
934                 return dev;
935         }
936 
937         if (!create)
938                 return NULL;
939 
940         return device_create_default(name, create > 1);
941 }
942 
943 static void
944 device_delete(struct device *dev)
945 {
946         if (!dev->avl.key)
947                 return;
948 
949         D(DEVICE, "Delete device '%s' from list", dev->ifname);
950         avl_delete(&devices, &dev->avl);
951         dev->avl.key = NULL;
952 }
953 
954 static int device_cleanup_cb(void *ctx, struct safe_list *list)
955 {
956         struct device_user *dep = container_of(list, struct device_user, list);
957         if (dep->cb)
958                 dep->cb(dep, DEV_EVENT_REMOVE);
959 
960         device_release(dep);
961         return 0;
962 }
963 
964 void device_cleanup(struct device *dev)
965 {
966         D(DEVICE, "Clean up device '%s'", dev->ifname);
967         safe_list_for_each(&dev->users, device_cleanup_cb, NULL);
968         safe_list_for_each(&dev->aliases, device_cleanup_cb, NULL);
969         device_delete(dev);
970 }
971 
972 static void __device_set_present(struct device *dev, bool state, bool force)
973 {
974         if (dev->present == state && !force)
975                 return;
976 
977         dev->present = state;
978         device_broadcast_event(dev, state ? DEV_EVENT_ADD : DEV_EVENT_REMOVE);
979 }
980 
981 void
982 device_refresh_present(struct device *dev)
983 {
984         bool state = dev->sys_present;
985 
986         if (dev->disabled || dev->deferred)
987                 state = false;
988 
989         D(DEVICE, "refresh device %s present: sys=%d disabled=%d deferred=%d",
990           dev->ifname, dev->sys_present, dev->disabled, dev->deferred);
991         __device_set_present(dev, state, false);
992 }
993 
994 void
995 device_set_auth_status(struct device *dev, bool value, struct blob_attr *vlans)
996 {
997         if (!value)
998                 vlans = NULL;
999         else if (!blob_attr_equal(vlans, dev->auth_vlans))
1000                 device_set_auth_status(dev, false, NULL);
1001 
1002         free(dev->auth_vlans);
1003         dev->auth_vlans = vlans ? blob_memdup(vlans) : NULL;
1004 
1005         if (dev->auth_status == value)
1006                 return;
1007 
1008         dev->auth_status = value;
1009         if (!dev->present)
1010                 return;
1011 
1012         if (dev->auth_status) {
1013                 device_broadcast_event(dev, DEV_EVENT_AUTH_UP);
1014                 return;
1015         }
1016 
1017         device_broadcast_event(dev, DEV_EVENT_LINK_DOWN);
1018         if (!dev->link_active)
1019                 return;
1020 
1021         device_broadcast_event(dev, DEV_EVENT_LINK_UP);
1022 }
1023 
1024 void _device_set_present(struct device *dev, bool state)
1025 {
1026         if (dev->sys_present == state)
1027                 return;
1028 
1029         D(DEVICE, "%s '%s' %s present", dev->type->name, dev->ifname, state ? "is now" : "is no longer" );
1030         dev->sys_present = state;
1031         if (!state)
1032                 __device_set_present(dev, state, true);
1033         else
1034                 device_refresh_present(dev);
1035         if (!state)
1036                 safe_list_for_each(&dev->users, device_release_cb, NULL);
1037 }
1038 
1039 void device_set_link(struct device *dev, bool state)
1040 {
1041         if (dev->link_active == state)
1042                 return;
1043 
1044         netifd_log_message(L_NOTICE, "%s '%s' link is %s\n", dev->type->name, dev->ifname, state ? "up" : "down" );
1045 
1046         dev->link_active = state;
1047         if (!state)
1048                 dev->auth_status = false;
1049         device_broadcast_event(dev, state ? DEV_EVENT_LINK_UP : DEV_EVENT_LINK_DOWN);
1050 }
1051 
1052 void device_set_ifindex(struct device *dev, int ifindex)
1053 {
1054         if (dev->ifindex == ifindex)
1055                 return;
1056 
1057         dev->ifindex = ifindex;
1058         device_broadcast_event(dev, DEV_EVENT_UPDATE_IFINDEX);
1059 }
1060 
1061 int device_set_ifname(struct device *dev, const char *name)
1062 {
1063         int ret = 0;
1064 
1065         if (!strcmp(dev->ifname, name))
1066                 return 0;
1067 
1068         if (strlen(name) > sizeof(dev->ifname) - 1) {
1069                 netifd_log_message(L_WARNING, "Cannot set device name: '%s' is longer than max size %zd\n",
1070                         name, sizeof(dev->ifname) - 1);
1071                 return -1;
1072         }
1073 
1074         if (dev->avl.key)
1075                 avl_delete(&devices, &dev->avl);
1076 
1077         strcpy(dev->ifname, name);
1078 
1079         if (dev->avl.key)
1080                 ret = avl_insert(&devices, &dev->avl);
1081 
1082         if (ret == 0)
1083                 device_broadcast_event(dev, DEV_EVENT_UPDATE_IFNAME);
1084 
1085         return ret;
1086 }
1087 
1088 static int device_refcount(struct device *dev)
1089 {
1090         struct list_head *list;
1091         int count = 0;
1092 
1093         list_for_each(list, &dev->users.list)
1094                 count++;
1095 
1096         list_for_each(list, &dev->aliases.list)
1097                 count++;
1098 
1099         return count;
1100 }
1101 
1102 static void
1103 __device_add_user(struct device_user *dep, struct device *dev)
1104 {
1105         struct safe_list *head;
1106 
1107         dep->dev = dev;
1108 
1109         if (dep->alias)
1110                 head = &dev->aliases;
1111         else
1112                 head = &dev->users;
1113 
1114         safe_list_add(&dep->list, head);
1115         D(DEVICE, "Add user for device '%s', refcount=%d", dev->ifname, device_refcount(dev));
1116 
1117         if (dep->cb && dev->present) {
1118                 dep->cb(dep, DEV_EVENT_ADD);
1119                 if (dev->active)
1120                         dep->cb(dep, DEV_EVENT_UP);
1121 
1122                 if (dev->link_active)
1123                         dep->cb(dep, DEV_EVENT_LINK_UP);
1124         }
1125 }
1126 
1127 void device_add_user(struct device_user *dep, struct device *dev)
1128 {
1129         if (dep->dev == dev)
1130                 return;
1131 
1132         if (dep->dev)
1133                 device_remove_user(dep);
1134 
1135         if (!dev)
1136                 return;
1137 
1138         __device_add_user(dep, dev);
1139 }
1140 
1141 static void
1142 device_free(struct device *dev)
1143 {
1144         free(dev->auth_vlans);
1145         free(dev->config);
1146         free(dev->hotplug_link);
1147         device_cleanup(dev);
1148         free(dev->tags);
1149         free(dev->config_auth_vlans);
1150         free(dev->extra_vlan);
1151         dev->type->free(dev);
1152 }
1153 
1154 static void
1155 __device_free_unused(struct uloop_timeout *timeout)
1156 {
1157         struct device *dev, *tmp;
1158 
1159         avl_for_each_element_safe(&devices, dev, avl, tmp) {
1160                 if (!safe_list_empty(&dev->users) ||
1161                         !safe_list_empty(&dev->aliases) ||
1162                         dev->current_config)
1163                         continue;
1164 
1165                 device_free(dev);
1166         }
1167 }
1168 
1169 void device_free_unused(void)
1170 {
1171         static struct uloop_timeout free_timer = {
1172                 .cb = __device_free_unused,
1173         };
1174 
1175         uloop_timeout_set(&free_timer, 1);
1176 }
1177 
1178 void device_remove_user(struct device_user *dep)
1179 {
1180         struct device *dev = dep->dev;
1181 
1182         if (!dep->dev)
1183                 return;
1184 
1185         dep->hotplug = false;
1186         if (dep->claimed)
1187                 device_release(dep);
1188 
1189         safe_list_del(&dep->list);
1190         dep->dev = NULL;
1191         D(DEVICE, "Remove user for device '%s', refcount=%d", dev->ifname, device_refcount(dev));
1192         device_free_unused();
1193 }
1194 
1195 void
1196 device_init_pending(void)
1197 {
1198         struct device *dev, *tmp;
1199 
1200         avl_for_each_element_safe(&devices, dev, avl, tmp) {
1201                 if (!dev->config_pending)
1202                         continue;
1203 
1204                 dev->type->config_init(dev);
1205                 dev->config_pending = false;
1206                 device_check_state(dev);
1207         }
1208 }
1209 
1210 bool
1211 device_check_ip6segmentrouting(void)
1212 {
1213         struct device *dev;
1214         bool ip6segmentrouting = false;
1215 
1216         avl_for_each_element(&devices, dev, avl)
1217                 ip6segmentrouting |= dev->settings.ip6segmentrouting;
1218 
1219         return ip6segmentrouting;
1220 }
1221 
1222 bool
1223 device_diff_live_apply(unsigned long *diff, uint64_t *apply_mask)
1224 {
1225         uint64_t d;
1226 
1227         if (sizeof(unsigned long) >= 8)
1228                 d = (uint64_t)diff[0];
1229         else
1230                 d = (uint64_t)diff[0] | ((uint64_t)diff[1] << 32);
1231 
1232         if (d & ~DEV_OPT_LIVE_APPLY_MASK) {
1233                 *apply_mask = 0;
1234                 return false;
1235         }
1236 
1237         *apply_mask = d;
1238         return true;
1239 }
1240 
1241 void
1242 device_apply_live_settings(struct device *dev, uint64_t apply_mask)
1243 {
1244         struct device_settings *s = &dev->settings;
1245         struct device_settings *os = &dev->orig_settings;
1246         uint64_t added   = apply_mask &  s->flags;
1247         uint64_t removed = apply_mask & ~s->flags;
1248 
1249         if (added)
1250                 system_if_apply_settings(dev, s, added);
1251 
1252         /*
1253          * For attrs dropped from UCI, restore the value captured at bringup.
1254          * orig_settings.flags still holds these bits because the previous
1255          * settings.flags did, and set_device_state() intersects the two.
1256          */
1257         if (removed) {
1258                 uint64_t restore = removed & os->valid_flags & os->flags;
1259 
1260                 if (restore)
1261                         system_if_apply_settings(dev, os, restore);
1262         }
1263 
1264         /*
1265          * Rebalance orig_settings.flags to match the new settings.flags so
1266          * an eventual teardown restores the right set.
1267          */
1268         os->flags &= ~apply_mask;
1269         os->flags |= added & os->valid_flags;
1270 }
1271 
1272 void
1273 device_init_config(struct device *dev, struct blob_attr *attr)
1274 {
1275         struct blob_attr *tb[__DEV_ATTR_MAX];
1276 
1277         memset(tb, 0, sizeof(tb));
1278         if (attr)
1279                 blobmsg_parse_attr(dev_attrs, __DEV_ATTR_MAX, tb, attr);
1280 
1281         device_init_settings(dev, tb);
1282 
1283         if (dev->type->reload)
1284                 dev->type->reload(dev, attr, tb);
1285 }
1286 
1287 static enum dev_change_type
1288 device_set_config(struct device *dev, struct device_type *type,
1289                   struct blob_attr *attr)
1290 {
1291         struct blob_attr *tb[__DEV_ATTR_MAX];
1292         struct blob_attr *tb_old[__DEV_ATTR_MAX];
1293         const struct uci_blob_param_list *cfg = type->config_params;
1294         unsigned long diff[2] = {};
1295         uint64_t apply_mask = 0;
1296         enum dev_change_type ret = DEV_CONFIG_APPLIED;
1297         bool has_old;
1298 
1299         if (type != dev->type)
1300                 return DEV_CONFIG_RECREATE;
1301 
1302         /*
1303          * Fast equality check for simple devices whose entire config is
1304          * device_attr_list. Types with a reload hook fold their own subtype
1305          * attrs into the diff below, so skip the shortcut for them.
1306          */
1307         if (!dev->type->reload && cfg == &device_attr_list &&
1308             uci_blob_check_equal(dev->config, attr, cfg))
1309                 return DEV_CONFIG_NO_CHANGE;
1310 
1311         memset(tb, 0, sizeof(tb));
1312         if (attr)
1313                 blobmsg_parse_attr(dev_attrs, __DEV_ATTR_MAX, tb, attr);
1314 
1315         has_old = dev->config != NULL;
1316         memset(tb_old, 0, sizeof(tb_old));
1317         if (has_old)
1318                 blobmsg_parse_attr(dev_attrs, __DEV_ATTR_MAX, tb_old, dev->config);
1319 
1320         if (has_old)
1321                 uci_blob_diff(tb, tb_old, &device_attr_list, diff);
1322 
1323         device_init_settings(dev, tb);
1324 
1325         if (has_old && !device_diff_live_apply(diff, &apply_mask))
1326                 ret = DEV_CONFIG_RESTART;
1327         else if (!has_old && !dev->type->reload && cfg == &device_attr_list)
1328                 /*
1329                  * Pre-refactor simple-device path returned RESTART whenever the
1330                  * blob equality check failed, including the first apply with
1331                  * dev->config == NULL. Match that so dev->present transitions
1332                  * stay bisect-identical.
1333                  */
1334                 ret = DEV_CONFIG_RESTART;
1335 
1336         if (dev->type->reload) {
1337                 enum dev_change_type sub_ret = dev->type->reload(dev, attr, tb);
1338 
1339                 if (sub_ret == DEV_CONFIG_RECREATE)
1340                         return DEV_CONFIG_RECREATE;
1341                 /*
1342                  * Preserve pre-refactor behaviour: some hooks (e.g. tunnel)
1343                  * report NO_CHANGE based on their own sub-attr equality check
1344                  * and expect the caller to treat the whole config as
1345                  * unchanged. Propagate that verdict regardless of whether the
1346                  * device-attr diff saw any changes.
1347                  */
1348                 if (sub_ret == DEV_CONFIG_NO_CHANGE)
1349                         return DEV_CONFIG_NO_CHANGE;
1350                 if (sub_ret == DEV_CONFIG_RESTART)
1351                         ret = DEV_CONFIG_RESTART;
1352         } else if (cfg != &device_attr_list) {
1353                 /*
1354                  * Type has no reload hook but a custom config_params. Pre-refactor
1355                  * this path returned DEV_CONFIG_RECREATE for any blob difference.
1356                  */
1357                 if (has_old && (diff[0] | diff[1]))
1358                         return DEV_CONFIG_RECREATE;
1359         }
1360 
1361         if (ret == DEV_CONFIG_APPLIED && apply_mask && dev->active)
1362                 device_apply_live_settings(dev, apply_mask);
1363 
1364         return ret;
1365 }
1366 
1367 enum dev_change_type
1368 device_apply_config(struct device *dev, struct device_type *type,
1369                     struct blob_attr *config)
1370 {
1371         enum dev_change_type change;
1372 
1373         change = device_set_config(dev, type, config);
1374         switch (change) {
1375                 case DEV_CONFIG_RESTART:
1376                 case DEV_CONFIG_APPLIED:
1377                         D(DEVICE, "Device '%s': config applied", dev->ifname);
1378                         config = blob_memdup(config);
1379                         free(dev->config);
1380                         dev->config = config;
1381                         if (change == DEV_CONFIG_RESTART && dev->present) {
1382                                 int ret = 0;
1383 
1384                                 device_set_present(dev, false);
1385                                 if (dev->active) {
1386                                         ret = dev->set_state(dev, false);
1387                                         if (!ret)
1388                                                 ret = dev->set_state(dev, true);
1389                                 }
1390                                 if (!ret)
1391                                         device_set_present(dev, true);
1392                         }
1393                         break;
1394                 case DEV_CONFIG_NO_CHANGE:
1395                         D(DEVICE, "Device '%s': no configuration change", dev->ifname);
1396                         break;
1397                 case DEV_CONFIG_RECREATE:
1398                         break;
1399         }
1400 
1401         return change;
1402 }
1403 
1404 static void
1405 device_migrate_users(struct list_head *head, struct device *dev)
1406 {
1407         struct device_user *dep;
1408 
1409         while (!list_empty(head)) {
1410                 dep = list_first_entry(head, struct device_user, list.list);
1411                 device_release(dep);
1412                 if (!dep->dev)
1413                         continue;
1414 
1415                 safe_list_del(&dep->list);
1416                 __device_add_user(dep, dev);
1417         }
1418 }
1419 
1420 static void
1421 device_replace(struct device *dev, struct device *odev)
1422 {
1423         if (odev->present)
1424                 device_set_present(odev, false);
1425 
1426         device_migrate_users(&odev->users.list, dev);
1427         device_migrate_users(&odev->aliases.list, dev);
1428 
1429         device_free(odev);
1430 }
1431 
1432 void
1433 device_reset_config(void)
1434 {
1435         struct device *dev;
1436 
1437         avl_for_each_element(&devices, dev, avl)
1438                 dev->current_config = false;
1439 }
1440 
1441 void
1442 device_reset_old(void)
1443 {
1444         struct device *dev, *tmp, *ndev;
1445 
1446         avl_for_each_element_safe(&devices, dev, avl, tmp) {
1447                 if (dev->current_config || dev->default_config)
1448                         continue;
1449 
1450                 if (dev->type != &simple_device_type)
1451                         continue;
1452 
1453                 ndev = device_create_default(dev->ifname, dev->external);
1454                 if (!ndev)
1455                         continue;
1456 
1457                 device_replace(ndev, dev);
1458         }
1459 }
1460 
1461 struct device *
1462 device_create(const char *name, struct device_type *type,
1463               struct blob_attr *config)
1464 {
1465         struct device *odev = NULL, *dev;
1466         enum dev_change_type change;
1467 
1468         odev = device_find(name);
1469         if (odev) {
1470                 odev->current_config = true;
1471                 change = device_apply_config(odev, type, config);
1472                 switch (change) {
1473                 case DEV_CONFIG_RECREATE:
1474                         D(DEVICE, "Device '%s': recreate device", odev->ifname);
1475                         device_delete(odev);
1476                         break;
1477                 default:
1478                         return odev;
1479                 }
1480         } else
1481                 D(DEVICE, "Create new device '%s' (%s)", name, type->name);
1482 
1483         config = blob_memdup(config);
1484         if (!config)
1485                 goto error;
1486 
1487         dev = type->create(name, type, config);
1488         if (!dev) {
1489                 free(config);
1490                 goto error;
1491         }
1492 
1493         dev->current_config = true;
1494         dev->config = config;
1495         if (odev)
1496                 device_replace(dev, odev);
1497 
1498         if (!config_init && dev->config_pending) {
1499                 type->config_init(dev);
1500                 dev->config_pending = false;
1501         }
1502 
1503         device_check_state(dev);
1504 
1505         return dev;
1506 
1507 error:
1508         /*
1509          * Re-insert the device removed for recreation: leaving it outside the
1510          * tree would strand it and its users permanently, since
1511          * __device_free_unused() only walks the tree
1512          */
1513         if (odev) {
1514                 odev->avl.key = odev->ifname;
1515                 avl_insert(&devices, &odev->avl);
1516         }
1517 
1518         return NULL;
1519 }
1520 
1521 void
1522 device_dump_status(struct blob_buf *b, struct device *dev)
1523 {
1524         struct device_settings st;
1525         void *c, *s;
1526 
1527         if (!dev) {
1528                 avl_for_each_element(&devices, dev, avl) {
1529                         if (!dev->present)
1530                                 continue;
1531                         c = blobmsg_open_table(b, dev->ifname);
1532                         device_dump_status(b, dev);
1533                         blobmsg_close_table(b, c);
1534                 }
1535 
1536                 return;
1537         }
1538 
1539         blobmsg_add_u8(b, "external", dev->external);
1540         blobmsg_add_u8(b, "present", dev->present);
1541         blobmsg_add_string(b, "type", dev->type->name);
1542 
1543         if (!dev->present)
1544                 return;
1545 
1546         blobmsg_add_u8(b, "up", !!dev->active);
1547         blobmsg_add_u8(b, "carrier", !!dev->link_active);
1548         blobmsg_add_u8(b, "auth_status", !!dev->auth_status);
1549 
1550         if (dev->tags)
1551                 blobmsg_add_blob(b, dev->tags);
1552 
1553         if (dev->type->dump_info)
1554                 dev->type->dump_info(dev, b);
1555         else
1556                 system_if_dump_info(dev, b);
1557 
1558         if (dev->active) {
1559                 device_merge_settings(dev, &st);
1560                 if (st.flags & DEV_OPT_MASTER) {
1561                         char buf[64], *devname;
1562 
1563                         devname = if_indextoname(st.master_ifindex, buf);
1564                         if (devname)
1565                                 blobmsg_add_string(b, "conduit", devname);
1566                 }
1567                 if (st.flags & DEV_OPT_MTU)
1568                         blobmsg_add_u32(b, "mtu", st.mtu);
1569                 if (st.flags & DEV_OPT_MTU6)
1570                         blobmsg_add_u32(b, "mtu6", st.mtu6);
1571                 if (st.flags & DEV_OPT_MACADDR)
1572                         blobmsg_add_string(b, "macaddr", format_macaddr(st.macaddr));
1573                 if (st.flags & DEV_OPT_TXQUEUELEN)
1574                         blobmsg_add_u32(b, "txqueuelen", st.txqueuelen);
1575                 if (st.flags & DEV_OPT_IPV6)
1576                         blobmsg_add_u8(b, "ipv6", st.ipv6);
1577                 if (st.flags & DEV_OPT_IP6SEGMENTROUTING)
1578                         blobmsg_add_u8(b, "ip6segmentrouting", st.ip6segmentrouting);
1579                 if (st.flags & DEV_OPT_PROMISC)
1580                         blobmsg_add_u8(b, "promisc", st.promisc);
1581                 if (st.flags & DEV_OPT_RPFILTER)
1582                         blobmsg_add_u32(b, "rpfilter", st.rpfilter);
1583                 if (st.flags & DEV_OPT_ACCEPTLOCAL)
1584                         blobmsg_add_u8(b, "acceptlocal", st.acceptlocal);
1585                 if (st.flags & DEV_OPT_IGMPVERSION)
1586                         blobmsg_add_u32(b, "igmpversion", st.igmpversion);
1587                 if (st.flags & DEV_OPT_MLDVERSION)
1588                         blobmsg_add_u32(b, "mldversion", st.mldversion);
1589                 if (st.flags & DEV_OPT_NEIGHREACHABLETIME) {
1590                         blobmsg_add_u32(b, "neigh4reachabletime", st.neigh4reachabletime);
1591                         blobmsg_add_u32(b, "neigh6reachabletime", st.neigh6reachabletime);
1592                 }
1593                 if (st.flags & DEV_OPT_NEIGHGCSTALETIME) {
1594                         blobmsg_add_u32(b, "neigh4gcstaletime", st.neigh4gcstaletime);
1595                         blobmsg_add_u32(b, "neigh6gcstaletime", st.neigh6gcstaletime);
1596                 }
1597                 if (st.flags & DEV_OPT_NEIGHLOCKTIME)
1598                         blobmsg_add_u32(b, "neigh4locktime", st.neigh4locktime);
1599                 if (st.flags & DEV_OPT_DADTRANSMITS)
1600                         blobmsg_add_u32(b, "dadtransmits", st.dadtransmits);
1601                 if (st.flags & DEV_OPT_MULTICAST_TO_UNICAST)
1602                         blobmsg_add_u8(b, "multicast_to_unicast", st.multicast_to_unicast);
1603                 if (st.flags & DEV_OPT_MULTICAST_ROUTER)
1604                         blobmsg_add_u32(b, "multicast_router", st.multicast_router);
1605                 if (st.flags & DEV_OPT_MULTICAST_FAST_LEAVE)
1606                         blobmsg_add_u8(b, "multicast_fast_leave", st.multicast_fast_leave);
1607                 if (st.flags & DEV_OPT_MULTICAST)
1608                         blobmsg_add_u8(b, "multicast", st.multicast);
1609                 if (st.flags & DEV_OPT_LEARNING)
1610                         blobmsg_add_u8(b, "learning", st.learning);
1611                 if (st.flags & DEV_OPT_UNICAST_FLOOD)
1612                         blobmsg_add_u8(b, "unicast_flood", st.unicast_flood);
1613                 if (st.flags & DEV_OPT_BROADCAST_FLOOD)
1614                         blobmsg_add_u8(b, "broadcast_flood", st.broadcast_flood);
1615                 if (st.flags & DEV_OPT_SENDREDIRECTS)
1616                         blobmsg_add_u8(b, "sendredirects", st.sendredirects);
1617                 if (st.flags & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST)
1618                         blobmsg_add_u8(b, "drop_v4_unicast_in_l2_multicast", st.drop_v4_unicast_in_l2_multicast);
1619                 if (st.flags & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST)
1620                         blobmsg_add_u8(b, "drop_v6_unicast_in_l2_multicast", st.drop_v6_unicast_in_l2_multicast);
1621                 if (st.flags & DEV_OPT_DROP_GRATUITOUS_ARP)
1622                         blobmsg_add_u8(b, "drop_gratuitous_arp", st.drop_gratuitous_arp);
1623                 if (st.flags & DEV_OPT_DROP_UNSOLICITED_NA)
1624                         blobmsg_add_u8(b, "drop_unsolicited_na", st.drop_unsolicited_na);
1625                 if (st.flags & DEV_OPT_ARP_ACCEPT)
1626                         blobmsg_add_u8(b, "arp_accept", st.arp_accept);
1627                 if (st.flags & DEV_OPT_AUTH)
1628                         blobmsg_add_u8(b, "auth", st.auth);
1629                 if (st.flags & DEV_OPT_GRO)
1630                         blobmsg_add_u8(b, "gro", st.gro);
1631                 if (st.flags & DEV_OPT_EEE)
1632                         blobmsg_add_u8(b, "eee", st.eee);
1633         }
1634 
1635         s = blobmsg_open_table(b, "statistics");
1636         if (dev->type->dump_stats)
1637                 dev->type->dump_stats(dev, b);
1638         else
1639                 system_if_dump_stats(dev, b);
1640         blobmsg_close_table(b, s);
1641 }
1642 
1643 static void __init simple_device_type_init(void)
1644 {
1645         device_type_add(&simple_device_type);
1646 }
1647 
1648 void device_hotplug_event(const char *name, bool add)
1649 {
1650         struct device *dev;
1651 
1652         netifd_ucode_hotplug_event(name, add);
1653 
1654         dev = device_find(name);
1655         if (!dev || dev->type != &simple_device_type)
1656                 return;
1657 
1658         device_set_present(dev, add);
1659 }
1660 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt