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

Sources/netifd/interface.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 <sys/types.h>
 18 #include <sys/wait.h>
 19 
 20 #include "netifd.h"
 21 #include "device.h"
 22 #include "interface.h"
 23 #include "interface-ip.h"
 24 #include "proto.h"
 25 #include "ubus.h"
 26 #include "config.h"
 27 #include "system.h"
 28 #include "wireless.h"
 29 
 30 struct vlist_tree interfaces;
 31 static LIST_HEAD(iface_all_users);
 32 
 33 enum {
 34         IFACE_ATTR_DEVICE,
 35         IFACE_ATTR_IFNAME, /* Backward compatibility */
 36         IFACE_ATTR_PROTO,
 37         IFACE_ATTR_AUTO,
 38         IFACE_ATTR_ZONE,
 39         IFACE_ATTR_JAIL,
 40         IFACE_ATTR_JAIL_DEVICE,
 41         IFACE_ATTR_JAIL_IFNAME,
 42         IFACE_ATTR_HOST_DEVICE,
 43         IFACE_ATTR_DEFAULTROUTE,
 44         IFACE_ATTR_PEERDNS,
 45         IFACE_ATTR_DNS,
 46         IFACE_ATTR_DNS_SEARCH,
 47         IFACE_ATTR_DNS_METRIC,
 48         IFACE_ATTR_RENEW,
 49         IFACE_ATTR_METRIC,
 50         IFACE_ATTR_INTERFACE,
 51         IFACE_ATTR_IP6ASSIGN,
 52         IFACE_ATTR_IP6HINT,
 53         IFACE_ATTR_IP4TABLE,
 54         IFACE_ATTR_IP6TABLE,
 55         IFACE_ATTR_IP6CLASS,
 56         IFACE_ATTR_DELEGATE,
 57         IFACE_ATTR_IP6IFACEID,
 58         IFACE_ATTR_FORCE_LINK,
 59         IFACE_ATTR_IP6WEIGHT,
 60         IFACE_ATTR_MAX
 61 };
 62 
 63 static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
 64         [IFACE_ATTR_DEVICE] = { .name = "device", .type = BLOBMSG_TYPE_STRING },
 65         [IFACE_ATTR_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING },
 66         [IFACE_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
 67         [IFACE_ATTR_AUTO] = { .name = "auto", .type = BLOBMSG_TYPE_BOOL },
 68         [IFACE_ATTR_ZONE] = { .name = "zone", .type = BLOBMSG_TYPE_STRING },
 69         [IFACE_ATTR_JAIL] = { .name = "jail", .type = BLOBMSG_TYPE_STRING },
 70         [IFACE_ATTR_JAIL_DEVICE] = { .name = "jail_device", .type = BLOBMSG_TYPE_STRING },
 71         [IFACE_ATTR_JAIL_IFNAME] = { .name = "jail_ifname", .type = BLOBMSG_TYPE_STRING },
 72         [IFACE_ATTR_HOST_DEVICE] = { .name = "host_device", .type = BLOBMSG_TYPE_STRING },
 73         [IFACE_ATTR_DEFAULTROUTE] = { .name = "defaultroute", .type = BLOBMSG_TYPE_BOOL },
 74         [IFACE_ATTR_PEERDNS] = { .name = "peerdns", .type = BLOBMSG_TYPE_BOOL },
 75         [IFACE_ATTR_METRIC] = { .name = "metric", .type = BLOBMSG_TYPE_INT32 },
 76         [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY },
 77         [IFACE_ATTR_RENEW] = { .name = "renew", .type = BLOBMSG_TYPE_BOOL },
 78         [IFACE_ATTR_DNS_SEARCH] = { .name = "dns_search", .type = BLOBMSG_TYPE_ARRAY },
 79         [IFACE_ATTR_DNS_METRIC] = { .name = "dns_metric", .type = BLOBMSG_TYPE_INT32 },
 80         [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
 81         [IFACE_ATTR_IP6ASSIGN] = { .name = "ip6assign", .type = BLOBMSG_TYPE_INT32 },
 82         [IFACE_ATTR_IP6HINT] = { .name = "ip6hint", .type = BLOBMSG_TYPE_STRING },
 83         [IFACE_ATTR_IP4TABLE] = { .name = "ip4table", .type = BLOBMSG_TYPE_STRING },
 84         [IFACE_ATTR_IP6TABLE] = { .name = "ip6table", .type = BLOBMSG_TYPE_STRING },
 85         [IFACE_ATTR_IP6CLASS] = { .name = "ip6class", .type = BLOBMSG_TYPE_ARRAY },
 86         [IFACE_ATTR_DELEGATE] = { .name = "delegate", .type = BLOBMSG_TYPE_BOOL },
 87         [IFACE_ATTR_IP6IFACEID] = { .name = "ip6ifaceid", .type = BLOBMSG_TYPE_STRING },
 88         [IFACE_ATTR_FORCE_LINK] = { .name = "force_link", .type = BLOBMSG_TYPE_BOOL },
 89         [IFACE_ATTR_IP6WEIGHT] = { .name = "ip6weight", .type = BLOBMSG_TYPE_INT32 },
 90 };
 91 
 92 const struct uci_blob_param_list interface_attr_list = {
 93         .n_params = IFACE_ATTR_MAX,
 94         .params = iface_attrs,
 95 };
 96 
 97 static void
 98 interface_set_main_dev(struct interface *iface, struct device *dev);
 99 static void
100 interface_event(struct interface *iface, enum interface_event ev);
101 
102 static void
103 interface_error_flush(struct interface *iface)
104 {
105         struct interface_error *error, *tmp;
106 
107         list_for_each_entry_safe(error, tmp, &iface->errors, list) {
108                 list_del(&error->list);
109                 free(error);
110         }
111 }
112 
113 static bool
114 interface_force_link(struct interface *iface)
115 {
116         struct device *dev = iface->main_dev.dev;
117 
118         if (dev && dev->settings.auth)
119                 return false;
120 
121         return iface->force_link;
122 }
123 
124 static void
125 interface_clear_errors(struct interface *iface)
126 {
127         /* don't flush the errors in case the configured protocol handler matches the
128            running protocol handler and is having the last error capability */
129         if (!(iface->proto &&
130               (iface->proto->handler->flags & PROTO_FLAG_LASTERROR) &&
131               (iface->proto->handler->name == iface->proto_handler->name)))
132                 interface_error_flush(iface);
133 }
134 
135 void interface_add_error(struct interface *iface, const char *subsystem,
136                          const char *code, const char **data, int n_data)
137 {
138         struct interface_error *error;
139         int i, len = 0;
140         int *datalen = NULL;
141         char *dest, *d_subsys, *d_code;
142 
143         /* if the configured protocol handler has the last error support capability,
144            errors should only be added if the running protocol handler matches the
145            configured one */
146         if (iface->proto &&
147             (iface->proto->handler->flags & PROTO_FLAG_LASTERROR) &&
148             (iface->proto->handler->name != iface->proto_handler->name))
149                 return;
150 
151         if (n_data) {
152                 len = n_data * sizeof(char *);
153                 datalen = alloca(len);
154                 for (i = 0; i < n_data; i++) {
155                         datalen[i] = strlen(data[i]) + 1;
156                         len += datalen[i];
157                 }
158         }
159 
160         error = calloc_a(sizeof(*error) + sizeof(char *) + len,
161                 &d_subsys, subsystem ? strlen(subsystem) + 1 : 0,
162                 &d_code, code ? strlen(code) + 1 : 0);
163         if (!error)
164                 return;
165 
166         /* Only keep the last flagged error, prevent this list grows unlimitted in case the
167            protocol can't be established (e.g auth failure) */
168         if (iface->proto_handler->flags & PROTO_FLAG_LASTERROR)
169                 interface_error_flush(iface);
170 
171         list_add_tail(&error->list, &iface->errors);
172 
173         dest = (char *) &error->data[n_data + 1];
174         for (i = 0; i < n_data; i++) {
175                 error->data[i] = dest;
176                 memcpy(dest, data[i], datalen[i]);
177                 dest += datalen[i];
178         }
179         error->data[n_data] = NULL;
180 
181         if (subsystem)
182                 error->subsystem = strcpy(d_subsys, subsystem);
183 
184         if (code)
185                 error->code = strcpy(d_code, code);
186 }
187 
188 static void
189 interface_data_del(struct interface *iface, struct interface_data *data)
190 {
191         avl_delete(&iface->data, &data->node);
192         free(data);
193 }
194 
195 static void
196 interface_data_flush(struct interface *iface)
197 {
198         struct interface_data *d, *tmp;
199 
200         avl_for_each_element_safe(&iface->data, d, node, tmp)
201                 interface_data_del(iface, d);
202 }
203 
204 int
205 interface_add_data(struct interface *iface, const struct blob_attr *data)
206 {
207         struct interface_data *n, *o;
208 
209         if (!blobmsg_check_attr(data, true))
210                 return UBUS_STATUS_INVALID_ARGUMENT;
211 
212         const char *name = blobmsg_name(data);
213         unsigned len = blob_pad_len(data);
214 
215         o = avl_find_element(&iface->data, name, o, node);
216         if (o) {
217                 if (blob_pad_len(o->data) == len && !memcmp(o->data, data, len))
218                         return 0;
219 
220                 interface_data_del(iface, o);
221         }
222 
223         n = calloc(1, sizeof(*n) + len);
224         if (!n)
225                 return UBUS_STATUS_UNKNOWN_ERROR;
226 
227         memcpy(n->data, data, len);
228         n->node.key = blobmsg_name(n->data);
229         avl_insert(&iface->data, &n->node);
230 
231         iface->updated |= IUF_DATA;
232         return 0;
233 }
234 
235 int interface_parse_data(struct interface *iface, const struct blob_attr *attr)
236 {
237         struct blob_attr *cur;
238         size_t rem;
239         int ret;
240 
241         iface->updated = 0;
242 
243         blob_for_each_attr(cur, attr, rem) {
244                 ret = interface_add_data(iface, cur);
245                 if (ret)
246                         return ret;
247         }
248 
249         if (iface->updated && iface->state == IFS_UP)
250                 interface_event(iface, IFEV_UPDATE);
251 
252         return 0;
253 }
254 
255 static void
256 interface_event(struct interface *iface, enum interface_event ev)
257 {
258         struct interface_user *dep, *tmp;
259         struct device *adev = NULL;
260 
261         list_for_each_entry_safe(dep, tmp, &iface->users, list)
262                 dep->cb(dep, iface, ev);
263 
264         list_for_each_entry_safe(dep, tmp, &iface_all_users, list)
265                 dep->cb(dep, iface, ev);
266 
267         switch (ev) {
268         case IFEV_UP:
269                 interface_error_flush(iface);
270                 adev = iface->l3_dev.dev;
271                 fallthrough;
272         case IFEV_DOWN:
273         case IFEV_UP_FAILED:
274                 alias_notify_device(iface->name, adev);
275                 break;
276         default:
277                 break;
278         }
279 }
280 
281 static void
282 interface_flush_state(struct interface *iface)
283 {
284         if (iface->l3_dev.dev)
285                 device_release(&iface->l3_dev);
286         interface_data_flush(iface);
287 }
288 
289 static void
290 mark_interface_down(struct interface *iface)
291 {
292         enum interface_state state = iface->state;
293 
294         if (state == IFS_DOWN)
295                 return;
296 
297         iface->link_up_event = false;
298         iface->state = IFS_DOWN;
299         switch (state) {
300         case IFS_UP:
301         case IFS_TEARDOWN:
302                 interface_event(iface, IFEV_DOWN);
303                 break;
304         case IFS_SETUP:
305                 interface_event(iface, IFEV_UP_FAILED);
306                 break;
307         default:
308                 break;
309         }
310         interface_ip_set_enabled(&iface->config_ip, false);
311         interface_ip_set_enabled(&iface->proto_ip, false);
312         interface_ip_flush(&iface->proto_ip);
313         interface_flush_state(iface);
314         system_flush_routes();
315 }
316 
317 static inline void
318 __set_config_state(struct interface *iface, enum interface_config_state s)
319 {
320         iface->config_state = s;
321 }
322 
323 static void
324 __interface_set_down(struct interface *iface, bool force)
325 {
326         enum interface_state state = iface->state;
327         switch (state) {
328         case IFS_UP:
329         case IFS_SETUP:
330                 iface->state = IFS_TEARDOWN;
331                 if (iface->dynamic)
332                         __set_config_state(iface, IFC_REMOVE);
333 
334                 if (state == IFS_UP)
335                         interface_event(iface, IFEV_DOWN);
336 
337                 interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, force);
338                 if (force)
339                         interface_flush_state(iface);
340                 break;
341 
342         case IFS_DOWN:
343                 if (iface->main_dev.dev)
344                         device_release(&iface->main_dev);
345                 break;
346         case IFS_TEARDOWN:
347         default:
348                 break;
349         }
350 }
351 
352 static int
353 __interface_set_up(struct interface *iface)
354 {
355         int ret;
356 
357         netifd_log_message(L_NOTICE, "Interface '%s' is setting up now\n", iface->name);
358 
359         iface->state = IFS_SETUP;
360         ret = interface_proto_event(iface->proto, PROTO_CMD_SETUP, false);
361         if (ret)
362                 mark_interface_down(iface);
363 
364         return ret;
365 }
366 
367 static void
368 interface_check_state(struct interface *iface)
369 {
370         bool link_state = iface->link_state || interface_force_link(iface);
371 
372         switch (iface->state) {
373         case IFS_UP:
374         case IFS_SETUP:
375                 if (!iface->enabled || !link_state) {
376                         iface->state = IFS_TEARDOWN;
377                         if (iface->dynamic)
378                                 __set_config_state(iface, IFC_REMOVE);
379 
380                         interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, false);
381                 }
382                 break;
383         case IFS_DOWN:
384                 if (!iface->available)
385                         return;
386 
387                 if (iface->autostart && iface->enabled && link_state && !config_init)
388                         __interface_set_up(iface);
389                 break;
390         default:
391                 break;
392         }
393 }
394 
395 static void
396 interface_set_enabled(struct interface *iface, bool new_state)
397 {
398         if (iface->enabled == new_state)
399                 return;
400 
401         netifd_log_message(L_NOTICE, "Interface '%s' is %s\n", iface->name, new_state ? "enabled" : "disabled");
402         iface->enabled = new_state;
403         interface_check_state(iface);
404 }
405 
406 static void
407 interface_set_link_state(struct interface *iface, bool new_state)
408 {
409         if (iface->link_state == new_state)
410                 return;
411 
412         netifd_log_message(L_NOTICE, "Interface '%s' has link connectivity %s\n", iface->name, new_state ? "" : "loss");
413         iface->link_state = new_state;
414         interface_check_state(iface);
415 
416         if (new_state && interface_force_link(iface) &&
417             iface->state == IFS_UP && !iface->link_up_event) {
418                 interface_event(iface, IFEV_LINK_UP);
419                 iface->link_up_event = true;
420         }
421 }
422 
423 static void
424 interface_ext_dev_cb(struct device_user *dep, enum device_event ev)
425 {
426         if (ev == DEV_EVENT_REMOVE)
427                 device_remove_user(dep);
428 }
429 
430 static void
431 interface_main_dev_cb(struct device_user *dep, enum device_event ev)
432 {
433         struct interface *iface;
434 
435         iface = container_of(dep, struct interface, main_dev);
436         switch (ev) {
437         case DEV_EVENT_ADD:
438                 interface_set_available(iface, true);
439                 break;
440         case DEV_EVENT_REMOVE:
441                 interface_set_available(iface, false);
442                 if (dep->dev && dep->dev->external && !dep->dev->sys_present)
443                         interface_set_main_dev(iface, NULL);
444                 break;
445         case DEV_EVENT_UP:
446                 interface_set_enabled(iface, true);
447                 break;
448         case DEV_EVENT_DOWN:
449                 interface_set_enabled(iface, false);
450                 break;
451         case DEV_EVENT_AUTH_UP:
452         case DEV_EVENT_LINK_UP:
453         case DEV_EVENT_LINK_DOWN:
454                 interface_set_link_state(iface, device_link_active(dep->dev));
455                 break;
456         case DEV_EVENT_TOPO_CHANGE:
457                 if (iface->renew)
458                         interface_proto_event(iface->proto, PROTO_CMD_RENEW, false);
459                 return;
460         default:
461                 break;
462         }
463 }
464 
465 static void
466 interface_l3_dev_cb(struct device_user *dep, enum device_event ev)
467 {
468         struct interface *iface;
469 
470         iface = container_of(dep, struct interface, l3_dev);
471         if (iface->l3_dev.dev == iface->main_dev.dev)
472                 return;
473 
474         switch (ev) {
475         case DEV_EVENT_LINK_DOWN:
476                 if (iface->proto_handler->flags & PROTO_FLAG_TEARDOWN_ON_L3_LINK_DOWN)
477                         interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, false);
478                 break;
479         default:
480                 break;
481         }
482 }
483 
484 void
485 interface_set_available(struct interface *iface, bool new_state)
486 {
487         if (iface->available == new_state)
488                 return;
489 
490         D(INTERFACE, "Interface '%s', available=%d", iface->name, new_state);
491         iface->available = new_state;
492 
493         if (new_state) {
494                 if (iface->autostart && !config_init)
495                         interface_set_up(iface);
496         } else
497                 __interface_set_down(iface, true);
498 }
499 
500 void
501 interface_add_user(struct interface_user *dep, struct interface *iface)
502 {
503         if (!iface) {
504                 list_add(&dep->list, &iface_all_users);
505                 return;
506         }
507 
508         dep->iface = iface;
509         list_add(&dep->list, &iface->users);
510         if (iface->state == IFS_UP)
511                 dep->cb(dep, iface, IFEV_UP);
512 }
513 
514 void
515 interface_remove_user(struct interface_user *dep)
516 {
517         list_del_init(&dep->list);
518         dep->iface = NULL;
519 }
520 
521 static void
522 interface_add_assignment_classes(struct interface *iface, struct blob_attr *list)
523 {
524         struct blob_attr *cur;
525         size_t rem;
526 
527         blobmsg_for_each_attr(cur, list, rem) {
528                 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
529                         continue;
530 
531                 if (!blobmsg_check_attr(cur, false))
532                         continue;
533 
534                 struct interface_assignment_class *c = malloc(sizeof(*c) + blobmsg_data_len(cur));
535                 memcpy(c->name, blobmsg_data(cur), blobmsg_data_len(cur));
536                 list_add(&c->head, &iface->assignment_classes);
537         }
538 }
539 
540 static void
541 interface_clear_assignment_classes(struct interface *iface)
542 {
543         while (!list_empty(&iface->assignment_classes)) {
544                 struct interface_assignment_class *c = list_first_entry(&iface->assignment_classes,
545                                 struct interface_assignment_class, head);
546                 list_del(&c->head);
547                 free(c);
548         }
549 }
550 
551 static void
552 interface_merge_assignment_data(struct interface *old, struct interface *new)
553 {
554         bool changed = (old->assignment_hint != new->assignment_hint ||
555                         old->assignment_length != new->assignment_length ||
556                         old->assignment_iface_id_selection != new->assignment_iface_id_selection ||
557                         old->assignment_weight != new->assignment_weight ||
558                         (old->assignment_iface_id_selection == IFID_FIXED &&
559                          memcmp(&old->assignment_fixed_iface_id, &new->assignment_fixed_iface_id,
560                                 sizeof(old->assignment_fixed_iface_id))) ||
561                         list_empty(&old->assignment_classes) != list_empty(&new->assignment_classes));
562 
563         struct interface_assignment_class *c;
564         list_for_each_entry(c, &new->assignment_classes, head) {
565                 /* Compare list entries one-by-one to see if there was a change */
566                 if (list_empty(&old->assignment_classes)) /* The new list is longer */
567                         changed = true;
568 
569                 if (changed)
570                         break;
571 
572                 struct interface_assignment_class *c_old = list_first_entry(&old->assignment_classes,
573                                 struct interface_assignment_class, head);
574 
575                 if (strcmp(c_old->name, c->name)) /* An entry didn't match */
576                         break;
577 
578                 list_del(&c_old->head);
579                 free(c_old);
580         }
581 
582         /* The old list was longer than the new one or the last entry didn't match */
583         if (!list_empty(&old->assignment_classes)) {
584                 interface_clear_assignment_classes(old);
585                 changed = true;
586         }
587 
588         list_splice_init(&new->assignment_classes, &old->assignment_classes);
589 
590         if (changed) {
591                 old->assignment_hint = new->assignment_hint;
592                 old->assignment_length = new->assignment_length;
593                 old->assignment_iface_id_selection = new->assignment_iface_id_selection;
594                 old->assignment_fixed_iface_id = new->assignment_fixed_iface_id;
595                 old->assignment_weight = new->assignment_weight;
596                 interface_refresh_assignments(true);
597         }
598 }
599 
600 static void
601 interface_alias_cb(struct interface_user *dep, struct interface *iface, enum interface_event ev)
602 {
603         struct interface *alias = container_of(dep, struct interface, parent_iface);
604         struct device *dev = iface->l3_dev.dev;
605 
606         switch (ev) {
607         case IFEV_UP:
608                 if (!dev)
609                         return;
610 
611                 interface_set_main_dev(alias, dev);
612                 interface_set_available(alias, true);
613                 break;
614         case IFEV_DOWN:
615         case IFEV_UP_FAILED:
616                 interface_set_available(alias, false);
617                 interface_set_main_dev(alias, NULL);
618                 break;
619         case IFEV_FREE:
620                 interface_remove_user(dep);
621                 break;
622         default:
623                 break;
624         }
625 }
626 
627 static void
628 interface_set_device_config(struct interface *iface, struct device *dev)
629 {
630         if (!dev || !dev->default_config)
631                 return;
632 
633         if (!iface->device_config &&
634             (!dev->iface_config || dev->config_iface != iface))
635                 return;
636 
637         dev->config_iface = iface;
638         dev->iface_config = iface->device_config;
639         device_apply_config(dev, dev->type, iface->config);
640 }
641 
642 static void
643 interface_claim_device(struct interface *iface)
644 {
645         struct interface *parent;
646         struct device *dev = NULL;
647 
648         if (iface->parent_iface.iface)
649                 interface_remove_user(&iface->parent_iface);
650 
651         if (iface->parent_ifname) {
652                 parent = vlist_find(&interfaces, iface->parent_ifname, parent, node);
653                 iface->parent_iface.cb = interface_alias_cb;
654                 interface_add_user(&iface->parent_iface, parent);
655         } else if (iface->device &&
656                 !(iface->proto_handler->flags & PROTO_FLAG_NODEV)) {
657                 dev = device_get(iface->device, true);
658                 if (!(iface->proto_handler->flags & PROTO_FLAG_NODEV_CONFIG))
659                         interface_set_device_config(iface, dev);
660         } else {
661                 dev = iface->ext_dev.dev;
662         }
663 
664         if (dev)
665                 interface_set_main_dev(iface, dev);
666 
667         if (iface->proto_handler->flags & PROTO_FLAG_INIT_AVAILABLE)
668                 interface_set_available(iface, true);
669 }
670 
671 static void
672 interface_cleanup_state(struct interface *iface)
673 {
674         interface_set_available(iface, false);
675 
676         interface_flush_state(iface);
677         interface_clear_errors(iface);
678         interface_set_proto_state(iface, NULL);
679 
680         interface_set_main_dev(iface, NULL);
681         interface_set_l3_dev(iface, NULL);
682 }
683 
684 static void
685 interface_cleanup(struct interface *iface)
686 {
687         struct interface_user *dep, *tmp;
688 
689         uloop_timeout_cancel(&iface->remove_timer);
690         device_remove_user(&iface->ext_dev);
691 
692         if (iface->parent_iface.iface)
693                 interface_remove_user(&iface->parent_iface);
694 
695         list_for_each_entry_safe(dep, tmp, &iface->users, list)
696                 interface_remove_user(dep);
697 
698         interface_clear_assignment_classes(iface);
699         interface_ip_flush(&iface->config_ip);
700         interface_cleanup_state(iface);
701 }
702 
703 static void
704 interface_do_free(struct interface *iface)
705 {
706         interface_event(iface, IFEV_FREE);
707         interface_cleanup(iface);
708         free(iface->config);
709         netifd_ubus_remove_interface(iface);
710         avl_delete(&interfaces.avl, &iface->node.avl);
711         if (iface->jail)
712                 free(iface->jail);
713         if (iface->jail_device)
714                 free(iface->jail_device);
715         if (iface->host_device)
716                 free(iface->host_device);
717 
718         free(iface);
719 }
720 
721 static void
722 interface_do_reload(struct interface *iface)
723 {
724         interface_event(iface, IFEV_RELOAD);
725         interface_cleanup_state(iface);
726         proto_init_interface(iface, iface->config);
727         interface_claim_device(iface);
728 }
729 
730 static void
731 interface_handle_config_change(struct interface *iface)
732 {
733         enum interface_config_state state = iface->config_state;
734 
735         iface->config_state = IFC_NORMAL;
736         switch(state) {
737         case IFC_NORMAL:
738                 break;
739         case IFC_RELOAD:
740                 interface_do_reload(iface);
741                 break;
742         case IFC_REMOVE:
743                 interface_do_free(iface);
744                 return;
745         }
746         if (iface->autostart)
747                 interface_set_up(iface);
748 }
749 
750 static void
751 interface_proto_event_cb(struct interface_proto_state *state, enum interface_proto_event ev)
752 {
753         struct interface *iface = state->iface;
754 
755         switch (ev) {
756         case IFPEV_UP:
757                 if (iface->state != IFS_SETUP) {
758                         if (iface->state == IFS_UP && iface->updated)
759                                 interface_event(iface, IFEV_UPDATE);
760                         return;
761                 }
762 
763                 if (!iface->l3_dev.dev)
764                         interface_set_l3_dev(iface, iface->main_dev.dev);
765 
766                 interface_ip_set_enabled(&iface->config_ip, true);
767                 interface_ip_set_enabled(&iface->proto_ip, true);
768                 system_flush_routes();
769                 iface->state = IFS_UP;
770                 iface->start_time = system_get_rtime();
771                 interface_event(iface, IFEV_UP);
772                 netifd_log_message(L_NOTICE, "Interface '%s' is now up\n", iface->name);
773                 break;
774         case IFPEV_DOWN:
775                 if (iface->state == IFS_DOWN)
776                         return;
777 
778                 netifd_log_message(L_NOTICE, "Interface '%s' is now down\n", iface->name);
779                 mark_interface_down(iface);
780                 interface_write_resolv_conf(iface->jail);
781                 if (iface->main_dev.dev && !(iface->config_state == IFC_NORMAL && iface->autostart && iface->available))
782                         device_release(&iface->main_dev);
783                 if (iface->l3_dev.dev)
784                         device_remove_user(&iface->l3_dev);
785                 interface_handle_config_change(iface);
786                 return;
787         case IFPEV_LINK_LOST:
788                 if (iface->state != IFS_UP)
789                         return;
790 
791                 netifd_log_message(L_NOTICE, "Interface '%s' has lost the connection\n", iface->name);
792                 mark_interface_down(iface);
793                 iface->state = IFS_SETUP;
794                 break;
795         default:
796                 return;
797         }
798 
799         interface_write_resolv_conf(iface->jail);
800 }
801 
802 void interface_set_proto_state(struct interface *iface, struct interface_proto_state *state)
803 {
804         if (iface->proto) {
805                 iface->proto->free(iface->proto);
806                 iface->proto = NULL;
807         }
808         iface->state = IFS_DOWN;
809         iface->proto = state;
810         if (!state)
811                 return;
812 
813         state->proto_event = interface_proto_event_cb;
814         state->iface = iface;
815 }
816 
817 struct interface *
818 interface_alloc(const char *name, struct blob_attr *config, bool dynamic)
819 {
820         struct interface *iface;
821         struct blob_attr *tb[IFACE_ATTR_MAX];
822         struct blob_attr *cur;
823         const char *proto_name = NULL;
824         char *iface_name;
825         bool force_link = false;
826 
827         iface = calloc_a(sizeof(*iface), &iface_name, strlen(name) + 1);
828         iface->name = strcpy(iface_name, name);
829         INIT_LIST_HEAD(&iface->errors);
830         INIT_LIST_HEAD(&iface->users);
831         INIT_LIST_HEAD(&iface->hotplug_list);
832         INIT_LIST_HEAD(&iface->assignment_classes);
833         interface_ip_init(iface);
834         avl_init(&iface->data, avl_strcmp, false, NULL);
835         iface->config_ip.enabled = false;
836 
837         iface->main_dev.cb = interface_main_dev_cb;
838         iface->l3_dev.cb = interface_l3_dev_cb;
839         iface->ext_dev.cb = interface_ext_dev_cb;
840 
841         blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb,
842                       blob_data(config), blob_len(config));
843 
844         iface->zone = NULL;
845         if ((cur = tb[IFACE_ATTR_ZONE]))
846                 iface->zone = strdup(blobmsg_get_string(cur));
847 
848         if ((cur = tb[IFACE_ATTR_PROTO]))
849                 proto_name = blobmsg_data(cur);
850 
851         proto_attach_interface(iface, proto_name);
852         if (iface->proto_handler->flags & PROTO_FLAG_FORCE_LINK_DEFAULT)
853                 force_link = true;
854 
855         iface->autostart = blobmsg_get_bool_default(tb[IFACE_ATTR_AUTO], true);
856         iface->renew = blobmsg_get_bool_default(tb[IFACE_ATTR_RENEW], true);
857         iface->force_link = blobmsg_get_bool_default(tb[IFACE_ATTR_FORCE_LINK], force_link);
858         iface->dynamic = dynamic;
859         iface->proto_ip.no_defaultroute =
860                 !blobmsg_get_bool_default(tb[IFACE_ATTR_DEFAULTROUTE], true);
861         iface->proto_ip.no_dns =
862                 !blobmsg_get_bool_default(tb[IFACE_ATTR_PEERDNS], true);
863 
864         if ((cur = tb[IFACE_ATTR_DNS]))
865                 interface_add_dns_server_list(&iface->config_ip, cur);
866 
867         if ((cur = tb[IFACE_ATTR_DNS_SEARCH]))
868                 interface_add_dns_search_list(&iface->config_ip, cur);
869 
870         if ((cur = tb[IFACE_ATTR_DNS_METRIC]))
871                 iface->dns_metric = blobmsg_get_u32(cur);
872 
873         if ((cur = tb[IFACE_ATTR_METRIC]))
874                 iface->metric = blobmsg_get_u32(cur);
875 
876         if ((cur = tb[IFACE_ATTR_IP6ASSIGN]))
877                 iface->assignment_length = blobmsg_get_u32(cur);
878 
879         /* defaults */
880         iface->assignment_iface_id_selection = IFID_FIXED;
881         iface->assignment_fixed_iface_id = in6addr_any;
882         iface->assignment_fixed_iface_id.s6_addr[15] = 1;
883 
884         if ((cur = tb[IFACE_ATTR_IP6IFACEID])) {
885                 const char *ifaceid = blobmsg_data(cur);
886                 if (!strcmp(ifaceid, "random")) {
887                         iface->assignment_iface_id_selection = IFID_RANDOM;
888                 }
889                 else if (!strcmp(ifaceid, "eui64")) {
890                         iface->assignment_iface_id_selection = IFID_EUI64;
891                 }
892                 else {
893                         /* we expect an IPv6 address with network id zero here -> fixed iface id
894                            if we cannot parse -> revert to iface id 1 */
895                         if (inet_pton(AF_INET6,ifaceid,&iface->assignment_fixed_iface_id) != 1 ||
896                                         iface->assignment_fixed_iface_id.s6_addr32[0] != 0 ||
897                                         iface->assignment_fixed_iface_id.s6_addr32[1] != 0) {
898                                 iface->assignment_fixed_iface_id = in6addr_any;
899                                 iface->assignment_fixed_iface_id.s6_addr[15] = 1;
900                                 netifd_log_message(L_WARNING, "Failed to parse ip6ifaceid for interface '%s', \
901                                                         falling back to iface id 1.\n", iface->name);
902                         }
903                 }
904         }
905 
906         iface->assignment_hint = -1;
907         if ((cur = tb[IFACE_ATTR_IP6HINT]))
908                 iface->assignment_hint = strtol(blobmsg_get_string(cur), NULL, 16) &
909                                 ~((1 << (64 - iface->assignment_length)) - 1);
910 
911         if ((cur = tb[IFACE_ATTR_IP6CLASS]))
912                 interface_add_assignment_classes(iface, cur);
913 
914         if ((cur = tb[IFACE_ATTR_IP6WEIGHT]))
915                 iface->assignment_weight = blobmsg_get_u32(cur);
916 
917         if ((cur = tb[IFACE_ATTR_IP4TABLE])) {
918                 if (!system_resolve_rt_table(blobmsg_data(cur), &iface->ip4table))
919                         D(INTERFACE, "Failed to resolve routing table: %s", (char *) blobmsg_data(cur));
920         }
921 
922         if ((cur = tb[IFACE_ATTR_IP6TABLE])) {
923                 if (!system_resolve_rt_table(blobmsg_data(cur), &iface->ip6table))
924                         D(INTERFACE, "Failed to resolve routing table: %s", (char *) blobmsg_data(cur));
925         }
926 
927         iface->proto_ip.no_delegation = !blobmsg_get_bool_default(tb[IFACE_ATTR_DELEGATE], true);
928 
929         iface->config_autostart = iface->autostart;
930         iface->jail = NULL;
931 
932         if ((cur = tb[IFACE_ATTR_JAIL])) {
933                 iface->jail = strdup(blobmsg_get_string(cur));
934                 iface->autostart = false;
935         }
936 
937         iface->jail_device = NULL;
938         if ((cur = tb[IFACE_ATTR_JAIL_DEVICE]))
939                 iface->jail_device = strdup(blobmsg_get_string(cur));
940         else if ((cur = tb[IFACE_ATTR_JAIL_IFNAME]))
941                 iface->jail_device = strdup(blobmsg_get_string(cur));
942 
943         iface->host_device = NULL;
944         if ((cur = tb[IFACE_ATTR_HOST_DEVICE]))
945                 iface->host_device = strdup(blobmsg_get_string(cur));
946 
947         return iface;
948 }
949 
950 static bool __interface_add(struct interface *iface, struct blob_attr *config, bool alias)
951 {
952         struct blob_attr *tb[IFACE_ATTR_MAX];
953         struct blob_attr *cur;
954         char *name = NULL;
955 
956         blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb,
957                       blob_data(config), blob_len(config));
958 
959         if (alias) {
960                 if ((cur = tb[IFACE_ATTR_INTERFACE]))
961                         iface->parent_ifname = blobmsg_data(cur);
962 
963                 if (!iface->parent_ifname)
964                         return false;
965         } else {
966                 cur = tb[IFACE_ATTR_DEVICE];
967                 if (!cur)
968                         cur = tb[IFACE_ATTR_IFNAME];
969                 if (cur)
970                         iface->device = blobmsg_data(cur);
971         }
972 
973         if (iface->dynamic) {
974                 name = strdup(iface->name);
975 
976                 if (!name)
977                         return false;
978         }
979 
980         iface->config = config;
981         vlist_add(&interfaces, &iface->node, iface->name);
982 
983         if (name) {
984                 iface = vlist_find(&interfaces, name, iface, node);
985                 free(name);
986 
987                 /* Don't delete dynamic interface on reload */
988                 if (iface)
989                         iface->node.version = -1;
990         }
991 
992         return true;
993 }
994 
995 bool
996 interface_add(struct interface *iface, struct blob_attr *config)
997 {
998         return __interface_add(iface, config, false);
999 }
1000 
1001 bool
1002 interface_add_alias(struct interface *iface, struct blob_attr *config)
1003 {
1004         if (iface->proto_handler->flags & PROTO_FLAG_NODEV)
1005                 return false;
1006 
1007         return __interface_add(iface, config, true);
1008 }
1009 
1010 void
1011 interface_set_l3_dev(struct interface *iface, struct device *dev)
1012 {
1013         bool enabled = iface->config_ip.enabled;
1014         bool claimed = iface->l3_dev.claimed;
1015 
1016         if (iface->l3_dev.dev == dev)
1017                 return;
1018 
1019         interface_ip_set_enabled(&iface->config_ip, false);
1020         interface_ip_set_enabled(&iface->proto_ip, false);
1021         interface_ip_flush(&iface->proto_ip);
1022         device_add_user(&iface->l3_dev, dev);
1023 
1024         if (dev) {
1025                 if (claimed) {
1026                         if (device_claim(&iface->l3_dev) < 0)
1027                                 return;
1028                 }
1029                 interface_ip_set_enabled(&iface->config_ip, enabled);
1030                 interface_ip_set_enabled(&iface->proto_ip, enabled);
1031         }
1032 }
1033 
1034 static void
1035 interface_set_main_dev(struct interface *iface, struct device *dev)
1036 {
1037         bool claimed = iface->l3_dev.claimed;
1038 
1039         if (iface->main_dev.dev == dev)
1040                 return;
1041 
1042         interface_set_available(iface, false);
1043         device_add_user(&iface->main_dev, dev);
1044         if (!dev) {
1045                 interface_set_link_state(iface, false);
1046                 return;
1047         }
1048 
1049         if (claimed) {
1050                 if (device_claim(&iface->l3_dev) < 0)
1051                         return;
1052         }
1053 
1054         if (!iface->l3_dev.dev)
1055                 interface_set_l3_dev(iface, dev);
1056 }
1057 
1058 static int
1059 interface_remove_link(struct interface *iface, struct device *dev,
1060                       struct blob_attr *vlan)
1061 {
1062         struct device *mdev = iface->main_dev.dev;
1063 
1064         if (mdev && mdev->hotplug_ops)
1065                 return mdev->hotplug_ops->del(mdev, dev, vlan);
1066 
1067         if (dev == iface->ext_dev.dev)
1068                 device_remove_user(&iface->ext_dev);
1069 
1070         if (!iface->main_dev.hotplug)
1071                 return UBUS_STATUS_INVALID_ARGUMENT;
1072 
1073         if (dev != iface->main_dev.dev)
1074                 return UBUS_STATUS_INVALID_ARGUMENT;
1075 
1076         interface_set_main_dev(iface, NULL);
1077         return 0;
1078 }
1079 
1080 static int
1081 interface_add_link(struct interface *iface, struct device *dev,
1082                    struct blob_attr *vlan, bool link_ext)
1083 {
1084         struct device *mdev = iface->main_dev.dev;
1085 
1086         if (mdev == dev && iface->state == IFS_UP)
1087                 return 0;
1088 
1089         if (iface->main_dev.hotplug)
1090                 interface_set_main_dev(iface, NULL);
1091 
1092         if (mdev) {
1093                 if (mdev->hotplug_ops)
1094                         return mdev->hotplug_ops->add(mdev, dev, vlan);
1095                 else
1096                         return UBUS_STATUS_NOT_SUPPORTED;
1097         }
1098 
1099         if (link_ext)
1100                 device_add_user(&iface->ext_dev, dev);
1101 
1102         interface_set_main_dev(iface, dev);
1103         iface->main_dev.hotplug = true;
1104         return 0;
1105 }
1106 
1107 int
1108 interface_handle_link(struct interface *iface, const char *name,
1109                       struct blob_attr *vlan, bool add, bool link_ext)
1110 {
1111         struct device *dev;
1112 
1113         dev = device_get(name, add ? (link_ext ? 2 : 1) : 0);
1114         if (!dev)
1115                 return UBUS_STATUS_NOT_FOUND;
1116 
1117         if (!add)
1118                 return interface_remove_link(iface, dev, vlan);
1119 
1120         interface_set_device_config(iface, dev);
1121         if (!link_ext)
1122                 device_set_present(dev, true);
1123 
1124         return interface_add_link(iface, dev, vlan, link_ext);
1125 }
1126 
1127 void
1128 interface_set_up(struct interface *iface)
1129 {
1130         int ret;
1131         const char *error = NULL;
1132 
1133         iface->autostart = true;
1134         wireless_check_network_enabled();
1135 
1136         if (iface->state != IFS_DOWN)
1137                 return;
1138 
1139         interface_clear_errors(iface);
1140         if (iface->available) {
1141                 if (iface->main_dev.dev) {
1142                         ret = device_claim(&iface->main_dev);
1143                         if (!ret)
1144                                 interface_check_state(iface);
1145                         else
1146                                 error = "DEVICE_CLAIM_FAILED";
1147                 } else {
1148                         ret = __interface_set_up(iface);
1149                         if (ret)
1150                                 error = "SETUP_FAILED";
1151                 }
1152         } else
1153                 error = "NO_DEVICE";
1154 
1155         if (error)
1156                 interface_add_error(iface, "interface", error, NULL, 0);
1157 }
1158 
1159 void
1160 interface_set_down(struct interface *iface)
1161 {
1162         if (!iface) {
1163                 vlist_for_each_element(&interfaces, iface, node)
1164                         __interface_set_down(iface, false);
1165         } else {
1166                 iface->autostart = false;
1167                 wireless_check_network_enabled();
1168                 __interface_set_down(iface, false);
1169         }
1170 }
1171 
1172 int
1173 interface_renew(struct interface *iface)
1174 {
1175         if (iface->state == IFS_TEARDOWN || iface->state == IFS_DOWN)
1176                 return -1;
1177 
1178         return interface_proto_event(iface->proto, PROTO_CMD_RENEW, false);
1179 }
1180 
1181 void
1182 interface_start_pending(void)
1183 {
1184         struct interface *iface;
1185 
1186         vlist_for_each_element(&interfaces, iface, node) {
1187                 if (iface->autostart)
1188                         interface_set_up(iface);
1189         }
1190 }
1191 
1192 void
1193 interface_start_jail(int netns_fd, const char *jail)
1194 {
1195         struct interface *iface;
1196 
1197         vlist_for_each_element(&interfaces, iface, node) {
1198                 if (!iface->jail || strcmp(iface->jail, jail))
1199                         continue;
1200 
1201                 system_link_netns_move(iface->main_dev.dev, netns_fd, iface->jail_device);
1202         }
1203 }
1204 
1205 void
1206 interface_stop_jail(int netns_fd)
1207 {
1208         struct interface *iface;
1209         char *orig_ifname;
1210 
1211         vlist_for_each_element(&interfaces, iface, node) {
1212                 orig_ifname = iface->host_device;
1213                 interface_set_down(iface);
1214                 system_link_netns_move(iface->main_dev.dev, netns_fd, orig_ifname);
1215         }
1216 }
1217 
1218 static void
1219 set_config_state(struct interface *iface, enum interface_config_state s)
1220 {
1221         __set_config_state(iface, s);
1222         if (iface->state == IFS_DOWN)
1223                 interface_handle_config_change(iface);
1224         else
1225                 __interface_set_down(iface, false);
1226 }
1227 
1228 void
1229 interface_update_start(struct interface *iface, const bool keep_old)
1230 {
1231         iface->updated = 0;
1232 
1233         if (!keep_old)
1234                 interface_ip_update_start(&iface->proto_ip);
1235 }
1236 
1237 void
1238 interface_update_complete(struct interface *iface)
1239 {
1240         interface_ip_update_complete(&iface->proto_ip);
1241 }
1242 
1243 static void
1244 interface_replace_dns(struct interface_ip_settings *new, struct interface_ip_settings *old)
1245 {
1246         vlist_simple_replace(&new->dns_servers, &old->dns_servers);
1247         vlist_simple_replace(&new->dns_search, &old->dns_search);
1248 }
1249 
1250 static bool
1251 interface_device_config_changed(struct interface *if_old, struct interface *if_new)
1252 {
1253         struct blob_attr *ntb[__DEV_ATTR_MAX];
1254         struct blob_attr *otb[__DEV_ATTR_MAX];
1255         struct device *dev = if_old->main_dev.dev;
1256         unsigned long diff[2] = {};
1257 
1258         BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8);
1259 
1260         if (!dev)
1261                 return false;
1262 
1263         if (if_old->device_config != if_new->device_config)
1264                 return true;
1265 
1266         if (!if_new->device_config)
1267                 return false;
1268 
1269         blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb,
1270                 blob_data(if_old->config), blob_len(if_old->config));
1271 
1272         blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, ntb,
1273                 blob_data(if_new->config), blob_len(if_new->config));
1274 
1275         uci_blob_diff(ntb, otb, &device_attr_list, diff);
1276 
1277         return diff[0] | diff[1];
1278 }
1279 
1280 static void
1281 interface_change_config(struct interface *if_old, struct interface *if_new)
1282 {
1283         struct blob_attr *old_config = if_old->config;
1284         bool reload = false, reload_ip = false, update_prefix_delegation = false;
1285 
1286 #define FIELD_CHANGED_STR(field)                                        \
1287                 ((!!if_old->field != !!if_new->field) ||                \
1288                  (if_old->field &&                                      \
1289                   strcmp(if_old->field, if_new->field) != 0))
1290 
1291         if (FIELD_CHANGED_STR(parent_ifname)) {
1292                 if (if_old->parent_iface.iface)
1293                         interface_remove_user(&if_old->parent_iface);
1294                 reload = true;
1295         }
1296 
1297         if (!reload && interface_device_config_changed(if_old, if_new))
1298                 reload = true;
1299 
1300         if (FIELD_CHANGED_STR(device) ||
1301             if_old->proto_handler != if_new->proto_handler)
1302                 reload = true;
1303 
1304         if (!if_old->proto_handler->config_params)
1305                 D(INTERFACE, "No config parameters for interface '%s'",
1306                   if_old->name);
1307         else if (!uci_blob_check_equal(if_old->config, if_new->config,
1308                                        if_old->proto_handler->config_params))
1309                 reload = true;
1310 
1311 #define UPDATE(field, __var) ({                                         \
1312                 bool __changed = (if_old->field != if_new->field);      \
1313                 if_old->field = if_new->field;                          \
1314                 __var |= __changed;                                     \
1315         })
1316 
1317         if_old->config = if_new->config;
1318         if (if_old->config_autostart != if_new->config_autostart) {
1319                 if (if_old->config_autostart)
1320                         reload = true;
1321 
1322                 if_old->autostart = if_new->config_autostart;
1323         }
1324 
1325         if_old->device_config = if_new->device_config;
1326         if_old->config_autostart = if_new->config_autostart;
1327         if (if_old->jail)
1328                 free(if_old->jail);
1329 
1330         if_old->jail = if_new->jail;
1331         if (if_old->jail)
1332                 if_old->autostart = false;
1333 
1334         if (if_old->jail_device)
1335                 free(if_old->jail_device);
1336 
1337         if_old->jail_device = if_new->jail_device;
1338 
1339         if (if_old->host_device)
1340                 free(if_old->host_device);
1341 
1342         if_old->host_device = if_new->host_device;
1343 
1344         if_old->device = if_new->device;
1345         if_old->parent_ifname = if_new->parent_ifname;
1346         if_old->dynamic = if_new->dynamic;
1347         if_old->proto_handler = if_new->proto_handler;
1348         if_old->force_link = if_new->force_link;
1349         if_old->dns_metric = if_new->dns_metric;
1350 
1351         if (if_old->proto_ip.no_delegation != if_new->proto_ip.no_delegation) {
1352                 if_old->proto_ip.no_delegation = if_new->proto_ip.no_delegation;
1353                 update_prefix_delegation = true;
1354         }
1355 
1356         if_old->proto_ip.no_dns = if_new->proto_ip.no_dns;
1357         interface_replace_dns(&if_old->config_ip, &if_new->config_ip);
1358 
1359         UPDATE(metric, reload_ip);
1360         UPDATE(proto_ip.no_defaultroute, reload_ip);
1361         UPDATE(ip4table, reload_ip);
1362         UPDATE(ip6table, reload_ip);
1363         interface_merge_assignment_data(if_old, if_new);
1364 
1365 #undef UPDATE
1366 
1367         if (reload) {
1368                 D(INTERFACE, "Reload interface '%s' because of config changes",
1369                   if_old->name);
1370                 interface_clear_errors(if_old);
1371                 set_config_state(if_old, IFC_RELOAD);
1372                 goto out;
1373         }
1374 
1375         if (reload_ip) {
1376                 bool config_ip_enabled = if_old->config_ip.enabled;
1377                 bool proto_ip_enabled = if_old->proto_ip.enabled;
1378 
1379                 interface_ip_set_enabled(&if_old->config_ip, false);
1380                 interface_ip_set_enabled(&if_old->proto_ip, false);
1381                 interface_ip_set_enabled(&if_old->proto_ip, proto_ip_enabled);
1382                 interface_ip_set_enabled(&if_old->config_ip, config_ip_enabled);
1383         }
1384 
1385         if (update_prefix_delegation)
1386                 interface_update_prefix_delegation(&if_old->proto_ip);
1387 
1388         interface_write_resolv_conf(if_old->jail);
1389         if (if_old->main_dev.dev)
1390                 interface_check_state(if_old);
1391 
1392 out:
1393         if_new->config = NULL;
1394         interface_cleanup(if_new);
1395         free(old_config);
1396         free(if_new);
1397 }
1398 
1399 static void
1400 interface_update(struct vlist_tree *tree, struct vlist_node *node_new,
1401                  struct vlist_node *node_old)
1402 {
1403         struct interface *if_old = container_of(node_old, struct interface, node);
1404         struct interface *if_new = container_of(node_new, struct interface, node);
1405 
1406         if (node_old && node_new) {
1407                 D(INTERFACE, "Update interface '%s'", if_new->name);
1408                 interface_change_config(if_old, if_new);
1409         } else if (node_old) {
1410                 D(INTERFACE, "Remove interface '%s'", if_old->name);
1411                 set_config_state(if_old, IFC_REMOVE);
1412         } else if (node_new) {
1413                 D(INTERFACE, "Create interface '%s'", if_new->name);
1414                 interface_event(if_new, IFEV_CREATE);
1415                 proto_init_interface(if_new, if_new->config);
1416                 interface_claim_device(if_new);
1417                 netifd_ubus_add_interface(if_new);
1418         }
1419 }
1420 
1421 
1422 static void __init
1423 interface_init_list(void)
1424 {
1425         vlist_init(&interfaces, avl_strcmp, interface_update);
1426         interfaces.keep_old = true;
1427         interfaces.no_delete = true;
1428 }
1429 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt