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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt