• 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 "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